0Pricing
Java Academy · บทเรียน

ลำดับชั้น ClassLoader และตัวโหลดแบบกำหนดเอง

ทำความเข้าใจตัวโหลดคลาสแบบ bootstrap, platform และ application พร้อมเขียน ClassLoader แบบกำหนดเอง

ลำดับชั้น ClassLoader และตัวโหลดแบบกำหนดเอง เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

ลำดับชั้นของ ClassLoader

JVM ใช้ลำดับชั้นของ ClassLoader แต่ละตัวโหลดมีตัวโหลดแม่ ก่อนจะโหลดคลาสด้วยตัวเอง ตัวโหลดจะมอบหมายงานให้ตัวโหลดแม่ก่อน (รูปแบบการมอบหมายแบบแม่ก่อน)

Bootstrap ClassLoader

Bootstrap ClassLoader โหลดคลาสหลักของ JDK (java.lang.*, java.util.*) โดยใช้งานโค้ดเนทีฟและไม่มีตัวโหลดแม่ที่เป็น Java; getParent() จะคืนค่า null

ClassLoader cl = String.class.getClassLoader();
System.out.println(cl); // null (bootstrap ClassLoader)

Platform ClassLoader (Java 9 ขึ้นไป)

Platform ClassLoader (เดิมเรียกว่า Extension ClassLoader) โหลดมอดูลจาก JDK ที่ไม่อยู่ในชุดของ bootstrap (java.sql, java.xml และอื่น ๆ) โดยมี bootstrap loader เป็นตัวโหลดแม่

ClassLoader platform = ClassLoader.getPlatformClassLoader();
System.out.println(platform.getClass().getName());
// jdk.internal.loader.ClassLoaders$PlatformClassLoader

Application (System) ClassLoader

Application ClassLoader โหลดคลาสของแอปพลิเคชันจากเส้นทางคลาส (-cp / CLASSPATH) โดยมี Platform ClassLoader เป็นตัวโหลดแม่ และเป็นตัวโหลดเริ่มต้นสำหรับโค้ดของผู้ใช้

ClassLoader app = ClassLoader.getSystemClassLoader();
System.out.println(app.getClass().getName());
// jdk.internal.loader.ClassLoaders$AppClassLoader

การมอบหมายแบบแม่ก่อน

เมื่อโหลด com.example.MyService AppClassLoader จะสอบถามตัวโหลดแม่ (Platform) ก่อน จากนั้น Platform จะสอบถาม Bootstrap เฉพาะเมื่อไม่มีตัวโหลดแม่ตัวใดโหลดได้ ตัวโหลดลูกจึงจะพยายามโหลดคลาสด้วยตัวเอง

เอกลักษณ์ของคลาสและ ClassLoader

คลาสสองคลาสที่มีชื่อเดียวกันแต่โหลดโดย ClassLoader คนละตัว จะถือว่าเป็นชนิดข้อมูลคนละชนิด การแปลงชนิดระหว่างคลาสเหล่านี้จะทำให้เกิด ClassCastException ซึ่งสำคัญในระบบปลั๊กอินและ OSGi

// Loaded by two different loaders → different Class objects
Class<?> c1 = loader1.loadClass("com.example.Plugin");
Class<?> c2 = loader2.loadClass("com.example.Plugin");
System.out.println(c1 == c2); // false!

การเขียน ClassLoader แบบกำหนดเอง

สืบทอดจาก ClassLoader และเขียนทับ findClass(String name) อ่านไบต์โค้ดจากแหล่งที่กำหนดเอง (JAR ที่เข้ารหัส เครือข่าย ฐานข้อมูล) แล้วเรียกใช้ defineClass

public class EncryptedClassLoader extends ClassLoader {
    public EncryptedClassLoader(ClassLoader parent) { super(parent); }
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        byte[] bytes = decrypt(readBytecodeFromVault(name));
        return defineClass(name, bytes, 0, bytes.length);
    }
}

URL ClassLoader: การโหลดจาก JAR

URLClassLoader โหลดคลาสจากรายการ URL (เส้นทางไฟล์หรือ URL HTTP) เหมาะสำหรับระบบปลั๊กอินที่เพิ่ม JAR ขณะโปรแกรมกำลังทำงาน

URL[] urls = { new File("plugins/my-plugin.jar").toURI().toURL() };
try (URLClassLoader loader = new URLClassLoader(urls, getClass().getClassLoader())) {
    Class<?> cls = loader.loadClass("com.example.PluginImpl");
    Plugin plugin = (Plugin) cls.getDeclaredConstructor().newInstance();
    plugin.start();
}

การปิด ClassLoader

ปิด URLClassLoader เสมอเมื่อใช้งานเสร็จ เนื่องจากตัวโหลดจะเปิด JAR ค้างไว้ การปิดตัวโหลดทำให้สามารถลบหรืออัปเดต JAR ได้ ใช้ try-with-resources

การมอบหมายแบบลูกก่อน (การโหลดแบบแยกส่วน)

คอนเทนเนอร์บางชนิด (Tomcat, Spring Boot fat JAR) กลับลำดับชั้น โดยให้ตัวโหลดลูกพยายามโหลดก่อน และจึงย้อนกลับไปใช้ตัวโหลดแม่เมื่อไม่พบเท่านั้น วิธีนี้แยกเวอร์ชันของไลบรารีระหว่างแอปพลิเคชันเว็บต่าง ๆ

การรั่วไหลของ ClassLoader

classloader จะถูกเก็บคืนโดย GC ก็ต่อเมื่อไม่มีคลาสใดที่โหลดโดยตัวโหลดนั้นยังเข้าถึงได้ ฟิลด์สแตติกที่เก็บออบเจ็กต์จากคลาสที่โหลดไว้จะทำให้ตัวโหลดคงอยู่ ซึ่งเป็นสาเหตุการรั่วไหลที่พบบ่อยเมื่อปรับใช้ใหม่

ตรวจสอบอย่างรวดเร็ว

ก่อนจะพยายามโหลดคลาสด้วยตัวเอง ClassLoader ทำสิ่งใด

สรุปทบทวน

ลำดับชั้นสามระดับ: Bootstrap → Platform → Application การมอบหมายแบบแม่ก่อนช่วยป้องกันการทำซ้ำของคลาส ตัวโหลดแบบกำหนดเองจะเขียนทับ findClass ใช้ URLClassLoader สำหรับระบบปลั๊กอิน และปิดตัวโหลดเพื่อป้องกันการรั่วไหล

คำถามที่พบบ่อย

บทเรียน “ลำดับชั้น ClassLoader และตัวโหลดแบบกำหนดเอง” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ลำดับชั้น ClassLoader และตัวโหลดแบบกำหนดเอง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ลำดับชั้น ClassLoader และตัวโหลดแบบกำหนดเอง”

ทำความเข้าใจตัวโหลดคลาสแบบ bootstrap, platform และ application พร้อมเขียน ClassLoader แบบกำหนดเอง คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “ลำดับชั้น ClassLoader และตัวโหลดแบบกำหนดเอง” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม

ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ระยะการโหลดคลาส: โหลด เชื่อมโยง เริ่มต้น
  2. ลำดับชั้น ClassLoader และตัวโหลดแบบกำหนดเอง
  3. ตรวจสอบไบต์โค้ดด้วย javap
  4. การคอมไพล์ JIT และการคอมไพล์แบบแบ่งระดับ
← กลับไปที่ Java Academy