Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

การเปลี่ยนแปลงของ Class Loaders ใน Java 9

ทุกโปรแกรม Java รันบน Java Virtual Machine (JVM) หลัง compile คลาส Java จะกลายเป็น platform-independent bytecode และเก็บเป็นไฟล์ .class เมื่อต้องการใช้ ClassLoader จะโหลดคลาสเข้า memory คลาสจะถูกนำเข้าสู่ Java environment เมื่อถูกอ้างอิงโดยชื่อ การโหลดคลาสทำโดย class loader เมื่อคลาสเริ่มรัน main() method เป็นจุดเริ่มต้น

การเปลี่ยนแปลงเล็กน้อยของ Class Loaders ใน Java 9

  • System class loader ไม่ใช่ instance ของ URLClassLoader อีกต่อไป เป็น internal class แทน เป็น default loader สำหรับคลาสใน modules
  • Extension class loader เปลี่ยนชื่อเป็น Platform class loader คลาสใน Java SE Platform มองเห็นได้ผ่าน platform class loader คลาสใน modules ภายใต้ Java Community Process แต่ไม่ใช่ส่วนของ Java SE platform ก็มองเห็นได้ผ่าน platform class loader เช่นกัน
  • Applications ไม่ควรพึ่งพา class loader ที่กำหนดว่าคลาสไหนใน Java SE Platform ถูก define โดย platform class loader ส่วนอื่นโดย bootstrap class loader
  • ถ้าโค้ดเดิมสร้าง class loader ด้วย bootstrap class loader เป็น parent ต้องเปลี่ยนมาใช้ platform class loader เป็น parent แทน
  • Platform class loader ไม่ใช่ instance ของ URLClassLoader เป็น internal class
  • Bootstrap class loader เป็น built-in class loader ของ JVM กำหนดคลาสของ critical modules เช่น java.base แอปพลิเคชันที่ deploy ด้วย -Xbootclasspath/a หรือสร้าง class loader ด้วย null เป็น parent อาจต้องปรับเปลี่ยน

ตัวอย่างโค้ด

public class ClassLoaderTest {
    public static void main(String args[]) {
        System.out.println("Class Loader Test");
        ClassLoaderTest test = new ClassLoaderTest();
        try {
            test.showClassLoaders();
        } catch(ClassNotFoundException cnfe) {
            System.out.println(cnfe.getMessage());
        }
    }
    
    public void showClassLoaders() throws ClassNotFoundException {
        System.out.println("Classloader of this class: " + ClassLoaderTest.class.getClassLoader());
        System.out.println("Classloader of Permission: " + java.sql.SQLPermission.class.getClassLoader());
        System.out.println("Classloader of LinkedList: " + java.util.LinkedList.class.getClassLoader());
    }
}

ผลลัพธ์

Class Loader Test
Classloader of this class: jdk.internal.loader.ClassLoaders$AppClassLoader@504bae78
Classloader of Permission: jdk.internal.loader.ClassLoaders$PlatformClassLoader@299a06ac
Classloader of LinkedList: null

คำอธิบายผลลัพธ์

  • AppClassLoader (jdk.internal.loader.ClassLoaders$AppClassLoader) - โหลด application classes (system class loader ใหม่)
  • PlatformClassLoader (jdk.internal.loader.ClassLoaders$PlatformClassLoader) - โหลด platform classes เช่น java.sql.SQLPermission
  • null - แสดงว่าโหลดโดย Bootstrap class loader (builtin classes เช่น java.util.LinkedList, java.lang.Object)

Class Loader Hierarchy ใน Java 9

Bootstrap Class Loader (null)
    ↑ parent
Platform Class Loader (internal class)
    ↑ parent
Application Class Loader (AppClassLoader - internal class)
    ↑ parent
Custom Class Loaders...

ผลกระทบต่อการ Migration

  • โค้ดที่ใช้ ClassLoader.getSystemClassLoader() ยังทำงานได้ แต่คืนค่า AppClassLoader (internal class)
  • โค้ดที่ cast เป็น URLClassLoader อาจล้มเหลว (ClassCastException)
  • การใช้ -Xbootclasspath/a ถูกจำกัด ควรใช้ --upgrade-module-path หรือ --patch-module แทน