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

ระยะการโหลดคลาส: โหลด เชื่อมโยง เริ่มต้น

ทำความเข้าใจกระบวนการโหลด ตรวจสอบ เตรียม แก้ไขการอ้างอิง และเริ่มต้นคลาส

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

วงจรการโหลดคลาส

คลาส Java ต้องผ่านสามระยะก่อนใช้งานได้ ได้แก่ การโหลด (ค้นหาและอ่านไบต์โค้ด) การเชื่อมโยง (ตรวจสอบ เตรียม และแก้การอ้างอิง) และการเริ่มต้น (เรียกใช้ตัวเริ่มต้นแบบ static)

ระยะที่ 1: การโหลด

ClassLoader อ่านไฟล์ .class (จากระบบไฟล์ JAR เครือข่าย หรือไบต์โค้ดที่สร้างขึ้น) แล้วสร้างออบเจ็กต์ Class<?> ในฮีปเพื่อแทนคลาสนั้น

// Trigger loading explicitly:
Class<?> c = Class.forName("com.example.MyService");
// The JVM delegates to the appropriate ClassLoader to find and load MyService.class

ระยะที่ 2a: การตรวจสอบ

ตัวตรวจสอบไบต์โค้ดจะตรวจว่าบไต์โค้ดที่โหลดมามีโครงสร้างถูกต้อง ปลอดภัยด้านชนิด และเป็นไปตามกฎของข้อกำหนด JVM ไบต์โค้ดที่ไม่ถูกต้อง (เช่น ถูกจัดการด้วย ASM อย่างไม่ถูกต้อง) จะทำให้เกิด VerifyError

ระยะที่ 2b: การเตรียมการ

JVM จัดสรรหน่วยความจำสำหรับฟิลด์แบบ static และกำหนดค่าเริ่มต้นให้ฟิลด์เหล่านั้น (0, false, null) ในระยะนี้ตัวเริ่มต้นแบบ static ยังไม่ได้ทำงาน

public class Config {
    static int timeout = 30;    // after preparation: timeout = 0 (default)
    static String host = "db"; // after preparation: host = null
    // Both get their real values only after Initialization
}

ระยะที่ 2c: การแก้การอ้างอิง

การอ้างอิงเชิงสัญลักษณ์ (ชื่อคลาส ลายเซ็นเมธอด) ในพูลค่าคงที่จะถูกแทนที่ด้วยการอ้างอิงโดยตรง (พอยน์เตอร์) ไปยังคลาสและเมธอดจริง การแก้การอ้างอิงอาจเลื่อนออกไปทำภายหลังได้ (การแก้แบบขี้เกียจ)

ระยะที่ 3: การเริ่มต้น

ตัวเริ่มต้นแบบ static (บล็อก static {}) และการกำหนดค่าให้ฟิลด์แบบ static จะทำงานตามลำดับที่ปรากฏในโค้ด นี่คือจังหวะที่ timeout = 30 และ host = "db" ทำงานจริง

public class Config {
    static int timeout;
    static String host;
    static {
        timeout = Integer.parseInt(System.getenv("TIMEOUT"));
        host    = System.getenv("DB_HOST");
        System.out.println("Config initialized");
    }
}

ทริกเกอร์การเริ่มต้นคลาส

การเริ่มต้นจะทำงานครั้งแรกเมื่อเกิดกรณีใดกรณีหนึ่งต่อไปนี้: (1) สร้างอินสแตนซ์ (2) เข้าถึงฟิลด์สแตติกที่ไม่ใช่ค่าคงที่ (3) เรียกเมธอดสแตติก (4) ใช้การสะท้อนผ่าน Class.forName() (โดยมี initialize=true) (5) เริ่มต้นคลาสย่อย

// forName with initialize=false skips static initializers:
Class<?> c = Class.forName("com.example.MyService", false, loader);

เมธอด <clinit>

JVM จะสร้างเมธอด <clinit> (ตัวเริ่มต้นคลาส) จากตัวเริ่มต้นสแตติกและการกำหนดค่าให้ฟิลด์สแตติกทั้งหมด เมธอดนี้ทำงานเพียงครั้งเดียวและปลอดภัยต่อเธรด — JVM รับประกันการไม่ให้ทำงานพร้อมกัน

ExceptionInInitializerError

หากตัวเริ่มต้นสแตติกทำให้เกิดข้อยกเว้น JVM จะครอบข้อยกเว้นนั้นด้วย ExceptionInInitializerError การพยายามใช้คลาสนี้ในภายหลังจะทำให้เกิด NoClassDefFoundError

static {
    if (System.getenv("DB_URL") == null)
        throw new RuntimeException("DB_URL not set"); // wrapped in ExceptionInInitializerError
}

ลำดับการเริ่มต้นแบบสแตติก

ตัวเริ่มต้นสแตติกจะทำงานตามลำดับที่ปรากฏในซอร์สโค้ด การอ้างอิงคลาสแบบวนรอบระหว่างการเริ่มต้นอาจทำให้คลาสถูกเริ่มต้นเพียงบางส่วน ซึ่งเป็นข้อควรระวังที่ทราบกันดีของรูปแบบ Initialization-on-Demand Holder

class A {
    static final int X = B.Y + 1; // accesses B before B is initialized!
}
class B {
    static final int Y = A.X + 1; // circular!
}

การสังเกตการโหลดคลาส

เปิดใช้บันทึกการโหลดคลาสด้วย -Xlog:class+load=info (JVM 9 ขึ้นไป) เพื่อดูว่าคลาสใดถูกโหลดจากที่ใด และโดย ClassLoader ใด

// JVM flag:
// java -Xlog:class+load=info:file=classload.log MyApp
// Output lines like:
// [info][class,load] com.example.MyService source: file:///app/app.jar

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

ตัวเริ่มต้นสแตติกทำงานในระยะใด

สรุปทบทวน

โหลด: อ่านไบต์โค้ด เชื่อมโยง: ตรวจสอบ → เตรียมการ (ค่าเริ่มต้นเป็นศูนย์) → แก้ไขการอ้างอิงเชิงสัญลักษณ์ เริ่มต้น: เรียกใช้ <clinit> การเริ่มต้นถูกกระตุ้นเมื่อมีการใช้งานครั้งแรกและปลอดภัยต่อเธรด การอ้างอิงแบบวนรอบระหว่างการเริ่มต้นทำให้เกิดข้อบกพร่องที่สังเกตได้ยาก

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

บทเรียน “ระยะการโหลดคลาส: โหลด เชื่อมโยง เริ่มต้น” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “ระยะการโหลดคลาส: โหลด เชื่อมโยง เริ่มต้น”

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

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

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

บทเรียน “ระยะการโหลดคลาส: โหลด เชื่อมโยง เริ่มต้น” ใช้เวลานานแค่ไหน

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

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

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

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

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