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

ตรวจสอบไบต์โค้ดด้วย 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

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

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