ระยะการโหลดคลาส: โหลด เชื่อมโยง เริ่มต้น
ทำความเข้าใจกระบวนการโหลด ตรวจสอบ เตรียม แก้ไขการอ้างอิง และเริ่มต้นคลาส
ระยะการโหลดคลาส: โหลด เชื่อมโยง เริ่มต้น เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ระยะการโหลดคลาส: โหลด เชื่อมโยง เริ่มต้น
- ลำดับชั้น ClassLoader และตัวโหลดแบบกำหนดเอง
- ตรวจสอบไบต์โค้ดด้วย javap
- การคอมไพล์ JIT และการคอมไพล์แบบแบ่งระดับ