ตัวโหลดชั้นเรียน
ตัวโหลดคลาส Java คือการโหลดคลาสที่ต้องการแบบไดนามิกใน JVM ที่รันไทม์ ตัวโหลดคลาส Java ขึ้นอยู่กับสามกลไก: มอบหมาย, มองเห็นและเดี่ยว
โหลดไฟล์. class ภายใต้ classPath ลงในหน่วยความจำและประมวลผลลงในไบต์ งานเหล่านี้ทำโดยตัวโหลดคลาส
ตัวโหลดคลาสเริ่มต้น
ระบบเริ่มต้นเป็นสามชั้นเรียน:
ตัวโหลดคลาสยังเป็นคลาส Java แต่ bootstrap ไม่ได้ รหัสตรวจสอบ:
คลาสสาธารณะ ClassloaderTest {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {system.out.println (system.class.getClassLoader ()); -เอาท์พุท: null
ถ้า System.out.println (System.class.getClassLoader (). ToString); ใช้รายงานข้อยกเว้นตัวชี้โมฆะ:
ข้อยกเว้นในเธรด "Main" java.lang.nullpointerexception ที่ com.iot.classloader.classloaderTest.main (classloaderTest.java:10) ที่ sun.reflect.nativemethodaccessorimpl.invoke0 sun.reflect.delegatingMethodaccessorimpl.invoke (มอบหมาย Methodaccessorimpl.java:43) ที่ java.lang.reflect.method.invoke (method.java:483) ที่ com.intellij.rt.execution.application
ดังที่เห็นได้ว่าคลาสระบบจะถูกโหลดโดยตัวโหลดคลาส bootstrap
กลไกผู้แทนชั้นเรียน
แผนผังต้นไม้ของชั้นเรียน
ตัวโหลดชั้นเรียน
ลำดับทั่วไปของคลาสโหลด:
วิธีการเขียนตัวโหลดคลาสที่กำหนดเอง
API:
คลาส LOADLOADER
รูปแบบการออกแบบวิธีการแม่แบบ
ชั้นเรียนหลัก:
loadclass (กระบวนการโหลดคลาส, แม่แบบ)
FindClass คลาสการโหลดตรรกะสำหรับการแทนที่คลาสย่อยที่เรียกว่าโดยวิธีการโหลด
defineclass รับไฟล์คลาสที่แปลงเป็น bytecode
subclass: แทนที่วิธี findclass
ตัวอย่าง:
ซอร์สโค้ดของวิธี loadclass
คลาสที่ได้รับการป้องกัน <?> loadclass (ชื่อสตริง, การแก้ไขบูลีน) พ่น classnotFoundException {ซิงโครไนซ์ (getClassLoadingLock (ชื่อ)) {// ก่อนตรวจสอบว่าคลาสได้รับการโหลดคลาสแล้ว <?> c = findloadedClass (ชื่อ) if (c == null) {long t0 = system.nanotime (); ลอง {ถ้า (parent! = null) {c = parent.loadclass (ชื่อ, เท็จ); } else {c = findbootstrapclassornull (ชื่อ); }} catch (classnotfoundexception e) {// classnotfoundexception โยนถ้าไม่พบคลาส // จากตัวโหลดคลาสแม่ที่ไม่ใช่ NULL} ถ้า (c == null) {// ถ้ายังไม่พบแล้วเรียก FindClass ตามลำดับ // เพื่อค้นหาคลาส t1 ยาว = system.nanotime (); c = findclass (ชื่อ); // นี่คือตัวโหลดคลาสที่กำหนด; บันทึกสถิติ sun.misc.perfcounter.getParentDelegationTime (). AddTime (T1 - T0); sun.misc.perfcounter.getfindclasstime (). addelapsedtime จาก (T1); sun.misc.perfcounter.getFindClasses (). เพิ่มขึ้น (); }} ถ้า (แก้ไข) {ResolveClass (c); } return c; -ตัวอย่างในเอกสาร API:
คลาส NetworkClassLoader ขยายคลาส loadler {สตริงโฮสต์; พอร์ต int; คลาสสาธารณะ findClass (ชื่อสตริง) {byte [] b = loadclassData (ชื่อ); ส่งคืน defineclass (ชื่อ, b, 0, b.length); } ไบต์ส่วนตัว [] loadclassData (ชื่อสตริง) {// โหลดข้อมูลคลาสจากการเชื่อมต่อ - - -