บทความนี้ส่วนใหญ่ศึกษาเนื้อหาที่เกี่ยวข้องของการโหลด Java แบบไดนามิกของไฟล์ JAR และคลาสดังต่อไปนี้
ไฟล์คลาสที่โหลดใน Java เป็นแบบไดนามิก กล่าวอีกนัยหนึ่งเราจะโหลดเฉพาะเมื่อเราใช้มันและถ้าเราไม่ใช้มันเราจะไม่โหลดคลาสของเรา
Java ให้กลไกสองแบบไดนามิกแก่เรา ประการแรกคือกลไกโดยนัย ประการที่สองคือกลไกการแสดงผล ดังนี้:
สองวิธี:
เมธอด class.forname () มีสองรูปแบบ:
public static Class forName(String className)public static Class forName(String className, boolean initialize,ClassLoader loader) การเรียกใช้เมธอด forname () ที่มีพารามิเตอร์เดียวเท่านั้นเทียบเท่ากับ class.forName (className, true, loader)
ทั้งสองวิธีจะต้องเชื่อมต่อกับวิธีการดั้งเดิม forname0 () ในตอนท้าย
forname () ที่มีสามพารามิเตอร์การโทรสุดท้ายคือ: forname0 (ชื่อ, เริ่มต้น, ตัวโหลด);
ไม่ว่าคุณจะใช้ใหม่ในการสร้างอินสแตนซ์คลาสที่แน่นอนหรือใช้เมธอด class.forName () ด้วยพารามิเตอร์เดียวเพียงขั้นตอนของ "การโหลดคลาส + การเรียกใช้บล็อกรหัสสแตติก" จะถูกบอกเป็นนัยภายใน
เมื่อใช้เมธอด class.forName () ที่มีพารามิเตอร์สามตัวหากพารามิเตอร์ที่สองเป็นเท็จตัวโหลดคลาสจะโหลดคลาสเท่านั้นและจะไม่เริ่มต้นบล็อกรหัสคงที่ เฉพาะเมื่อคลาสถูกสร้างอินสแตนซ์จะเริ่มต้นบล็อกรหัสแบบคงที่ บล็อกรหัสคงที่จะเริ่มต้นเมื่อคลาสถูกสร้างอินสแตนซ์เป็นครั้งแรก
classloader ใช้ในการโหลดคลาส เมื่อมีการโหลดคลาสคลาสทั้งหมดที่อ้างอิงโดยคลาสนี้จะถูกโหลดและการโหลดนี้จะถูกเรียกซ้ำ กล่าวคือหากหมายถึง B และ B หมายถึง C จากนั้นเมื่อโหลด A จะโหลด B และเมื่อโหลด B เมื่อ B จะโหลด C ด้วย เรียกซ้ำจนกระทั่งคลาสที่ต้องการทั้งหมดโหลดได้ดี
แพ็คเกจ com.demo.test; นำเข้า java.io.bytearrayoutputstream นำเข้า java.io.file; นำเข้า java.io.fileinputstream; นำเข้า java.io.filenotfoundexception; นำเข้า java.io.ioException; java.lang.reflect.method; นำเข้า java.net.malformedurlexception; นำเข้า java.net.url; นำเข้า java.net.urlclassloader; คลาสสาธารณะ DynamicloadDemo {enum fileType, คลาสคลาสอื่น ๆ โยน filenotfoundexception {class <?> cls = findloadedclass (ชื่อ); ถ้า (cls! = null) {return cls;} fileInputStream fis = ใหม่ fileInputStream (ไฟล์); bytearrayputTream baos = new bytearrayputstream (); fis.read (บัฟเฟอร์); if (len == -1) {break;} baos.write (บัฟเฟอร์, 0, len);} // fileinputstream ของการดำเนินการที่ว่างเปล่า ไม่จำเป็นต้องใช้ที่นี่ดังนั้นจึงว่างเปล่า //baos.flush (); byte [] data = baos.tobytearray (); return defineclass (null, data, 0, data.length);} catch (ioexception e) {e.printstacktrace ()} {try {try {baos.close () {fis.close ();} catch (ioexception e) {e.printstacktrace ();}} return null;}} โมฆะคงที่สาธารณะหลัก (สตริง [] args) {สตริง classname = "com.demo.test.helloworld"; {String LowerPath = path.toLowerCase (); fileType fileType = fileType.other; if (lowerPath.endswith (". jar") || underpath.endswith (". zip")) {fileType = fileType. == fileType.other) {return;} ไฟล์ไฟล์ = ไฟล์ใหม่ (พา ธ ); ถ้า (! file.exists ()) {return;} ลอง {url url = file.touri (). tourl (); system.out.println (url.toString () urlclassloader (url ใหม่ [] {url}, thread.currentthread (). getContextclassloader ()); cls = classloader.loadclass (className); break; case class: myclassloader myclassloader = new MyClassLoader (); cls = myclasslass {return;} // ฟิลด์ตัวแปรอินสแตนซ์ = cls.getDeclaredField ("hello"); ถ้า (! โมฆะ); if (! staticMethod.isaccessible ()) {staticMethod.setAccessible (จริง);} // ถ้าค่าคืนของฟังก์ชันเป็นโมฆะ, nullstaticmethod.invoke (cls, null); {method.setAccessible (true);} Object ret = method.invoke (cls.newinstance (), "Hello World"); System.out.println (ret);} catch (malformedurlexception e) {e.printstacktrace (); {E.PrintStackTrace ();} catch (SecurityException E) {E.printStackTrace ();} catch (unlendalAccessException e) {E.printStackTrace ();} catch (orderalargumentException e) {E.PrintStackTrace ();} catch (nosuchfieldexception e) {e.printstacktrace ();} catch (filenotfoundexception e) {e.printstacktrace ();}}}}}}}}ผลลัพธ์:
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้เกี่ยวกับการวิเคราะห์ Java Dynamic Loading Jar และอินสแตนซ์ไฟล์คลาส ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน เพื่อนที่สนใจสามารถอ้างถึงหัวข้ออื่น ๆ ที่เกี่ยวข้องในเว็บไซต์นี้ต่อไป หากมีข้อบกพร่องใด ๆ โปรดฝากข้อความไว้เพื่อชี้ให้เห็น ขอบคุณเพื่อนที่ให้การสนับสนุนเว็บไซต์นี้!