- 把java文件編譯生成class文件,
// 編寫HelloByteCode.java
public class HelloByteCode {
public static void main(String[] args) {
HelloByteCode obj = new HelloByteCode();
}
}
- 通過命令行生成class文件
通過Android Studio idea 查看生成的class文件,由此也可以看出,默認(rèn)構(gòu)造函數(shù)就在這里生成了
// HelloByteCode.class
public class HelloByteCode {
public HelloByteCode() {
}
public static void main(String[] var0) {
new HelloByteCode();
}
}
其中javac有很多參數(shù)可用,可以通過javac --help查看
javac --help
用法: javac <options> <source files>
其中, 可能的選項(xiàng)包括:
@<filename> 從文件讀取選項(xiàng)和文件名
-Akey[=value] 傳遞給注釋處理程序的選項(xiàng)
--add-modules <模塊>(,<模塊>)*
除了初始模塊之外要解析的根模塊; 如果 <module>
為 ALL-MODULE-PATH, 則為模塊路徑中的所有模塊。
--boot-class-path <path>, -bootclasspath <path>
覆蓋引導(dǎo)類文件的位置
--class-path <path>, -classpath <path>, -cp <path>
指定查找用戶類文件和注釋處理程序的位置
-d <directory> 指定放置生成的類文件的位置
-deprecation 輸出使用已過時(shí)的 API 的源位置
--enable-preview 啟用預(yù)覽語言功能。要與 -source 或 --release 一起使用。
-encoding <encoding> 指定源文件使用的字符編碼
-endorseddirs <dirs> 覆蓋簽名的標(biāo)準(zhǔn)路徑的位置
-extdirs <dirs> 覆蓋所安裝擴(kuò)展的位置
-g 生成所有調(diào)試信息
-g:{lines,vars,source} 只生成某些調(diào)試信息
-g:none 不生成任何調(diào)試信息
-h <directory> 指定放置生成的本機(jī)標(biāo)頭文件的位置
--help, -help, -? 輸出此幫助消息
--help-extra, -X 輸出額外選項(xiàng)的幫助
-implicit:{none,class} 指定是否為隱式引用文件生成類文件
-J<flag> 直接將 <標(biāo)記> 傳遞給運(yùn)行時(shí)系統(tǒng)
--limit-modules <模塊>(,<模塊>)*
限制可觀察模塊的領(lǐng)域
--module <模塊>(,<模塊>)*, -m <模塊>(,<模塊>)*
只編譯指定的模塊,請(qǐng)檢查時(shí)間戳
--module-path <path>, -p <path>
指定查找應(yīng)用程序模塊的位置
--module-source-path <module-source-path>
指定查找多個(gè)模塊的輸入源文件的位置
--module-version <版本> 指定正在編譯的模塊版本
-nowarn 不生成任何警告
-parameters 生成元數(shù)據(jù)以用于方法參數(shù)的反射
-proc:{none,only} 控制是否執(zhí)行注釋處理和/或編譯。
-processor <class1>[,<class2>,<class3>...]
要運(yùn)行的注釋處理程序的名稱; 繞過默認(rèn)的搜索進(jìn)程
--processor-module-path <path>
指定查找注釋處理程序的模塊路徑
--processor-path <path>, -processorpath <path>
指定查找注釋處理程序的位置
-profile <profile> 請(qǐng)確保使用的 API 在指定的配置文件中可用
--release <release> 針對(duì)特定發(fā)行版進(jìn)行編譯。支持的發(fā)行版:7, 8, 9, 10, 11, 12
-s <directory> 指定放置生成的源文件的位置
--source <release>, -source <release>
提供與指定發(fā)行版的源兼容性。支持的發(fā)行版:7, 8, 9, 10, 11, 12
--source-path <path>, -sourcepath <path>
指定查找輸入源文件的位置
--system <jdk>|none 覆蓋系統(tǒng)模塊位置
--target <release>, -target <release>
生成針對(duì)特定 VM 版本的類文件。支持的版本:7, 8, 9, 10, 11, 12
--upgrade-module-path <path>
覆蓋可升級(jí)模塊位置
-verbose 輸出有關(guān)編譯器正在執(zhí)行的操作的消息
--version, -version 版本信息
-Werror 出現(xiàn)警告時(shí)終止編譯
其中javac -g HelloByteCode.java 可以生成測試信息,大家可以自行嘗試
- 查看字節(jié)碼
通過命令行方式
javap -c -verbose HelloByteCode.class
javap -c -verbose HelloByteCode.class
Classfile /Users/xxxDesktop/java/HelloByteCode.class
Last modified 2022年9月29日; size 288 bytes
MD5 checksum b572cf2c2ccd067ad41d5c137a875273
Compiled from "HelloByteCode.java"
public class HelloByteCode
minor version: 0
major version: 56
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #2 // HelloByteCode
super_class: #4 // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 1
Constant pool:
#1 = Methodref #4.#13 // java/lang/Object."<init>":()V
#2 = Class #14 // HelloByteCode
#3 = Methodref #2.#13 // HelloByteCode."<init>":()V
#4 = Class #15 // java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = Utf8 Code
#8 = Utf8 LineNumberTable
#9 = Utf8 main
#10 = Utf8 ([Ljava/lang/String;)V
#11 = Utf8 SourceFile
#12 = Utf8 HelloByteCode.java
#13 = NameAndType #5:#6 // "<init>":()V
#14 = Utf8 HelloByteCode
#15 = Utf8 java/lang/Object
{
public HelloByteCode();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=1
0: new #2 // class HelloByteCode
3: dup
4: invokespecial #3 // Method "<init>":()V
7: astore_1
8: return
LineNumberTable:
line 3: 0
line 4: 8
}
如果是帶-g測試信息的class文件,效果是如下,多了額外的本地變量信息
javap -c -verbose HelloByteCode.class
Classfile /Users/hzhenx/Desktop/java/HelloByteCode.class
Last modified 2022年9月29日; size 415 bytes
MD5 checksum 05c705e182f58d3b5aa49c28d9e70d1d
Compiled from "HelloByteCode.java"
public class HelloByteCode
minor version: 0
major version: 56
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #2 // HelloByteCode
super_class: #4 // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 1
Constant pool:
#1 = Methodref #4.#19 // java/lang/Object."<init>":()V
#2 = Class #20 // HelloByteCode
#3 = Methodref #2.#19 // HelloByteCode."<init>":()V
#4 = Class #21 // java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = Utf8 Code
#8 = Utf8 LineNumberTable
#9 = Utf8 LocalVariableTable
#10 = Utf8 this
#11 = Utf8 LHelloByteCode;
#12 = Utf8 main
#13 = Utf8 ([Ljava/lang/String;)V
#14 = Utf8 args
#15 = Utf8 [Ljava/lang/String;
#16 = Utf8 obj
#17 = Utf8 SourceFile
#18 = Utf8 HelloByteCode.java
#19 = NameAndType #5:#6 // "<init>":()V
#20 = Utf8 HelloByteCode
#21 = Utf8 java/lang/Object
{
public HelloByteCode();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LHelloByteCode;
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=1
0: new #2 // class HelloByteCode
3: dup
4: invokespecial #3 // Method "<init>":()V
7: astore_1
8: return
LineNumberTable:
line 3: 0
line 4: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 args [Ljava/lang/String;
8 1 1 obj LHelloByteCode;
}
SourceFile: "HelloByteCode.java"
其中可以看到多了
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 args [Ljava/lang/String;
8 1 1 obj LHelloByteCode;
也可以通過Android Studio 的插件jclasslib可視化去查看
-
Android Stuido 安裝插件
1. 打開Preferences
進(jìn)入Plugins,搜索jclasslib
然后點(diǎn)擊安裝,重啟ide
-
使用jclasslib查看字節(jié)碼
IDE打開class文件
View->Show bytecode

各種信息直觀展示
至于怎么讀懂字節(jié)碼后面更新



