Class 文件採用類 C 結構體格式,順序包含:
魔數 (0xCAFEBABE) → 版本號 → 常量池 → 訪問標誌 → 類/父類/接口索引
→ 字段表 → 方法表 → 屬性表
public class Demo {
private String str1, str2;
private int num1, num2;
public static final String STATIC_DATA = \"hello world\";
private void sayHello1() { System.out.println(\"method1\"); }
private void sayHello2() { System.out.println(\"method2\"); }
public void sayHello3() { System.out.println(\"method3\"); }
}
執行 javap -verbose Demo > Demo.txt 關鍵輸出解讀:
major version: 49 → JDK 1.5(50=1.6, 58=1.4)。高版本 JVM 可執行低版本 Class。#1 = Class #2、#2 = Asciz Demo、#13 = String #14、#14 = Asciz hello world 等,統一管理字面量、符號引用。<init>()V,調用 super.<init>()。sayHello1、sayHello2 不出現在反編譯輸出中(默認只顯示 public/protected),需加 -private 參數。getstatic System.out → ldc \"method3\" → invokevirtual println → return。public class TestString {
public String testString(String s1, String s2) {
return s1 + s2;
}
public String testStringBuffer(StringBuffer sb, String s) {
return sb.append(s).toString();
}
}
javap -c TestString 對比:
| 方法 | 字節碼指令數 | 關鍵操作 |
|---|---|---|
testString | ~18 条 | new StringBuilder → dup → invokestatic String.valueOf → invokespecial StringBuilder.<init> → invokevirtual append → invokevirtual toString |
testStringBuffer | ~8 条 | aload_1 → aload_2 → invokevirtual append → invokevirtual toString |
結論:+ 拼接隱式創建 StringBuilder、調用 valueOf、構造器、兩次虛方法調用;直接用 StringBuffer/Builder 省去中間步驟,效率顯著更高。且 StringBuilder (非線程安全) 比 StringBuffer 更快,單線程首選。
javap -c -v:完整字節碼 + 行號表 + 局部變量表。jclasslib (IDEA 插件/獨立 GUI):可視化字節碼結構、常量池、控制流圖。ASM/ByteBuddy:字節碼操作框架,用於 AOP、動態代理、編譯器插件開發。閱讀字節碼是理解 JVM 執行模型、診疑難性能問題、開發框架中間件的核心硬功夫。