字節(jié)碼其實是一個二進制流文件,按照JVM規(guī)范排列的0101數(shù)字,我們也可以使用010 Editor編輯器打開查看:

image.png
這里使用十六進制表示,那么這又是什么意思呢?
根據(jù)Oracle官方文檔說明,一個字節(jié)碼文件應(yīng)包含以下信息:
ClassFile {
u4 magic; // 魔數(shù),4字節(jié),必須以CA FE BA BE 開頭
u2 minor_version; // javac的次版本號,2字節(jié)
u2 major_version; // javac的主版本號,2字節(jié)
u2 constant_pool_count; //常量池數(shù)量,2字節(jié)
cp_info constant_pool[constant_pool_count-1]; //常量池數(shù)組,長度不定
u2 access_flags; //訪問標(biāo)識符,2字節(jié)
u2 this_class; // 當(dāng)前類索引,2字節(jié)
u2 super_class; // 父類索引,2字節(jié)
u2 interfaces_count; // 接口索引,2字節(jié)
u2 interfaces[interfaces_count]; // 接口數(shù)組
u2 fields_count; // 字段表數(shù)量
field_info fields[fields_count]; // 字段數(shù)組
u2 methods_count; //方法數(shù)
method_info methods[methods_count]; //方法數(shù)組
u2 attributes_count; //屬性表數(shù)量
attribute_info attributes[attributes_count];
}
-
常量池數(shù)據(jù)區(qū):數(shù)據(jù)區(qū)是由(constant_pool_count-1)個cp_info結(jié)構(gòu)組成,一個cp_info結(jié)構(gòu)對應(yīng)一個常量。在字節(jié)碼中共有14種類型的cp_info,每種類型的結(jié)構(gòu)都是固定的。image.png
-
訪問標(biāo)識,JVM規(guī)范規(guī)定了如下圖的訪問標(biāo)志(Access_Flag)
image.png
image.png
需要注意的是,JVM并沒有窮舉所有的訪問標(biāo)志,而是使用按位或操作來進行描述的,比如某個類的修飾符為public final,則對應(yīng)的訪問修飾符的值為ACC_PUBLIC | ACC_FINAL,即0x0001 | 0x0010=0x0011
-
當(dāng)前類索引,父類索引,接口索引可以根據(jù)索引值去常量池查找
image.png
也可以在AS中安裝jclasslib插件,點擊view->show ByteCode With jclasslib查看:

image.png
也可以使用命令行查看:
D:\desktop> javac StringOperation.java
D:\desktop> javap -v StringOperation.class
不過上面的發(fā)匯編結(jié)果,main 函數(shù)無法看到LocalVariableTable
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=6, args_size=1
0: ldc #7 // String a
2: astore_1
3: ldc #7 // String a
5: astore_2
9: dup
10: ldc #7 // String a
12: invokespecial #11 // Method java/lang/String."<init>":(Ljava/lang/String;)V
18: astore 4
20: aload_2
21: invokedynamic #16, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String;
26: astore 5
28: return
LineNumberTable:
line 3: 0
line 4: 3
line 5: 6
line 6: 16
line 7: 20
line 8: 28
// 這里沒有LocalVariableTable
}
SourceFile: "StringOperation.java"
修改下編譯選項,就可以看到了
D:\desktop> javac -g StringOperation.java
D:\desktop> javap -v StringOperation.class



