ตรวจสอบไบต์โค้ดด้วย javap
ถอดคลายไฟล์คลาสด้วย javap -c เพื่อทำความเข้าใจว่าโครงสร้างของ Java แปลเป็นไบต์โค้ดอย่างไร
ตรวจสอบไบต์โค้ดด้วย javap เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดจึงต้องตรวจสอบไบต์โค้ด
การทำความเข้าใจไบต์โค้ดช่วยให้เห็นว่า JVM เรียกใช้โค้ด Java ของคุณจริง ๆ อย่างไร นอกจากนี้ยังช่วยแก้ไขปัญหาประสิทธิภาพ ทำความเข้าใจการเพิ่มประสิทธิภาพของคอมไพเลอร์ และตรวจสอบว่าโค้ดที่คอมไพเลอร์สร้างขึ้นโดยอัตโนมัติ (แลมบ์ดา คลาสภายใน) ทำงานตามที่คาดไว้
การใช้งาน javap เบื้องต้น
javap ClassName แสดง API สาธารณะของคลาส (ลายเซ็นเมธอด การประกาศฟิลด์) โดยอ่านไฟล์ .class จากไดเรกทอรีปัจจุบันหรือเส้นทางคลาส
# Compile first:
javac User.java
# Display public API:
javap User
# Output:
# public class User {
# public java.lang.String getName();
# public int getAge();
# }การแยกชิ้นส่วนไบต์โค้ดด้วย -c
javap -c User แสดงชุดคำสั่งของ JVM (รหัสปฏิบัติการ) สำหรับแต่ละเมธอด นี่คือมุมมองหลักสำหรับทำความเข้าใจลำดับการทำงาน
# javap -c User
# public java.lang.String getName();
# Code:
# 0: aload_0
# 1: getfield #2 // Field name:Ljava/lang/String;
# 4: areturnเอาต์พุตแบบละเอียดด้วย -v
javap -v User เพิ่มพูลค่าคงที่ แฟล็กการเข้าถึง ขนาดสแตก และตารางข้อยกเว้น ซึ่งจำเป็นสำหรับการวิเคราะห์เชิงลึกและการแก้ไขข้อบกพร่องของ ClassCastException
# javap -v User
# Constant pool:
# #1 = Methodref #5.#22 // java/lang/Object."<init>":()V
# #2 = Fieldref #4.#23 // User.name:Ljava/lang/String;
# ...คำสั่งไบต์โค้ดที่พบบ่อย
ควรรู้จักรหัสปฏิบัติการที่ใช้บ่อยที่สุด: aload_0 (โหลด this), getfield, putfield, invokevirtual, invokespecial (ตัวสร้าง/สมาชิกส่วนตัว), invokestatic, invokedynamic (แลมบ์ดา), return, areturn
แลมบ์ดาและ invokedynamic
นิพจน์แลมบ์ดาจะถูกคอมไพล์เป็นคำสั่ง invokedynamic การเรียกใช้ครั้งแรกใช้ LambdaMetafactory เพื่อสร้างคลาส ส่วนการเรียกครั้งถัดไปจะนำคลาสเดิมกลับมาใช้ซ้ำ javap -v จะแสดงตารางเมธอด bootstrap
// Java:
list.forEach(s -> System.out.println(s));
// Compiles to invokedynamic — javap shows:
// invokedynamic #4,0 // InvokeDynamic #0:accept:()Ljava/util/function/Consumer;การเพิ่มประสิทธิภาพการต่อสตริง
javac สมัยใหม่ใช้ invokedynamic สำหรับ "Hello " + name แทน StringBuilder javap -v จะแสดงเมธอด bootstrap ของ StringConcatFactory
// Java 9+ string concat:
String s = "Hello " + name;
// Compiles to:
// invokedynamic #5,0 // InvokeDynamic #1:makeConcatWithConstantsการดูการเข้าถึงคลาสภายใน
เมื่อคลาสภายนอกเข้าถึงฟิลด์ส่วนตัวของคลาสภายใน (หรือกลับกัน) คอมไพเลอร์จะสร้างเมธอดสังเคราะห์ access$000 ขึ้นมา javap -p (สมาชิกส่วนตัว) จะแสดงเมธอดเหล่านี้
# javap -p OuterClass
# static int access$000(OuterClass);
# -- synthetic bridge method generated by the compilerการตรวจสอบต้นทุนของการห่อชนิดอัตโนมัติ
การห่อชนิดอัตโนมัติจะถูกคอมไพล์เป็นการเรียก Integer.valueOf() หรือ int.intValue() ใช้ javap -c เพื่อยืนยันว่ามีการห่อชนิดเกิดขึ้น และตัดสินใจว่าจะใช้ชนิดข้อมูลพื้นฐานหรือไม่
// Java:
List<Integer> list = new ArrayList<>();
list.add(42); // autoboxing
// Bytecode:
// bipush 42
// invokestatic java/lang/Integer.valueOf:(I)Ljava/lang/Integer;การอ่าน try-catch จากไบต์โค้ด
ตัวจัดการข้อยกเว้นจะปรากฏเป็นรายการในตารางข้อยกเว้น ซึ่งดูได้ด้วย javap -v แต่ละรายการจะแสดงจุดเริ่มต้นของ try จุดสิ้นสุดของ try ตัวจัดการ และชนิดที่ดักจับ
# Exception table:
# from to target type
# 2 10 15 Class java/io/IOException
# -- means: if IOException in bytes 2-10, jump to handler at byte 15ส่วนหัวไฟล์คลาส
ส่วนหัวไฟล์คลาสประกอบด้วยเลขมหัศจรรย์ (CAFEBABE) เวอร์ชันหลัก/รอง และแฟล็กการเข้าถึง javap -v จะแสดงเวอร์ชันหลัก ซึ่งระบุรุ่น Java ที่ใช้คอมไพล์คลาส
# javap -v User
# minor version: 0
# major version: 61 <- Java 17
# flags: ACC_PUBLIC, ACC_SUPERตรวจสอบอย่างรวดเร็ว
แฟล็กใดของ javap ที่แสดงรหัสปฏิบัติการของ JVM สำหรับแต่ละเมธอด
สรุปทบทวน
ใช้ javap -c สำหรับดูรหัสปฏิบัติการ และ javap -v สำหรับดูรายละเอียดทั้งหมด ควรรู้จักรหัสปฏิบัติการสำคัญ ได้แก่ invokevirtual, invokespecial, invokedynamic, getfield ตรวจสอบแลมบ์ดา การห่อชนิด และการต่อสตริงเพื่อทำความเข้าใจเอาต์พุตของคอมไพเลอร์
คำถามที่พบบ่อย
บทเรียน “ตรวจสอบไบต์โค้ดด้วย javap” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ตรวจสอบไบต์โค้ดด้วย javap” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ตรวจสอบไบต์โค้ดด้วย javap”
ถอดคลายไฟล์คลาสด้วย javap -c เพื่อทำความเข้าใจว่าโครงสร้างของ Java แปลเป็นไบต์โค้ดอย่างไร คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “ตรวจสอบไบต์โค้ดด้วย javap” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม
ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ระยะการโหลดคลาส: โหลด เชื่อมโยง เริ่มต้น
- ลำดับชั้น ClassLoader และตัวโหลดแบบกำหนดเอง
- ตรวจสอบไบต์โค้ดด้วย javap
- การคอมไพล์ JIT และการคอมไพล์แบบแบ่งระดับ