Java9之class檔案格式變動
Java9之class檔案格式變動
Java9已經於2017年09月27日釋出。Java9引入了很多新特性,其中最重要的特性,或者說最大的變化,無疑就是模組化了。為了支援模組化,Java從方方面面都進行了改進,包括class檔案格式。已經有很多文章介紹Java9模組化,因此本文並不打算成為另一篇模組化入門文章。本文主要介紹Java9相較Java8在class檔案格式方面的變動。
測試程式碼
本文將基於模組mymod
進行討論,目錄結構如下所示:
j9cf
└── src
└── mymod
├── a
│ └── b
│ ├── MyImpl.java
│ ├── MyService.java
│ └── c
│ └── HelloWorld.java
└── module-info.java
其中a.b
包裡定義了MyService
和MyImpl
兩個類,程式碼如下所示:
package a.b;
public class MyService {}
package a.b;
public class MyImpl extends MyService {}
a.b.c
包裡定義了HelloWorld
主類,程式碼如下所示:
package a.b.c;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
module-info.java檔案則對mymod
模組進行定義,程式碼如下所示:
module mymod {
requires java.base;
requires static java.sql;
requires transitive java.xml;
exports a.b.c;
exports a.b to java.sql, java.xml;
opens a.b to java.sql, java.xml;
uses a.b.MyService;
provides a.b.MyService with a.b.MyImpl;
}
使用下面的命令對模組進行編譯:
cd j9cf
path/to/java9/bin/javac \
-d mods --module-source-path src \
src/mymod/module-info.java \
src/mymod/a/b/c/HelloWorld.java
使用下面的命令將模組打包成jar格式:
cd j9cf
path/to/bin/jar --create \
--file mymod-1.0.jar \
--main-class a.b.c.HelloWorld \
--module-version 1.0 \
-C mods/mymod .
上面兩個命令執行完之後,j9cf目錄結構如下所示:
j9cf
├── mymod-1.0.jar
├── mods
│ └── mymod
│ ├── a
│ │ └── b
│ │ ├── MyImpl.class
│ │ ├── MyService.class
│ │ └── c
│ │ └── HelloWorld.class
│ └── module-info.class
└── src
└── mymod
├── a
│ └── b
│ ├── MyImpl.java
│ ├── MyService.java
│ └── c
│ └── HelloWorld.java
└── module-info.java
class檔案檢視工具
Java自帶了命令列工具javap,可以反編譯並分析class檔案格式。不過為了更直觀的觀察class檔案,本文使用圖形化工具classpy。
class檔案格式變動
class檔案格式主要在四個方面有變動:版本號、類存取標誌、常量池、類屬性,下面分別進行介紹。
版本號
class檔案大版本號由Java8的52(0x34)增加到了53(0x35),如下圖所示:
類存取標誌
類的存取標誌(access_flags)新增加了ACC_MODULE(0x8000)標誌位,表示class檔案描述的是一個模組,如下所示:
常量池
常量池增加了CONSTANT_Module_info和CONSTANT_Package_info兩種常量。
CONSTANT_Module_info
CONSTANT_Module_info的tag值是19,表示一個模組,其結構如下所示:
CONSTANT_Module_info {
u1 tag;
u2 name_index;
}
比如mymod模組module-info.class檔案常量池的第15個常量就是一個CONSTANT_Module_info常量,表示mymod模組自己,如下圖所示:
CONSTANT_Package_info
CONSTANT_Package_info的tag值是20,表示模組輸出(Export)或者開啟(Open)的包,其結構和CONSTANT_Module_info一樣,如下所示:
CONSTANT_Package_info {
u1 tag;
u2 name_index;
}
比如mymod模組module-info.class檔案常量池的第7個常量就是一個CONSTANT_Package_info常量,表示a.b
包,如下圖所示:
類屬性
增加了三個預定義屬性:Module_attribute、ModulePackages_attribute和ModuleMainClass_attribute。
ModulePackages_attribute
ModulePackages_attribute屬性記錄和模組相關(比如輸出或使用等)的包,結構如下所示:
ModulePackages_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 package_count;
u2 package_index[package_count];
}
其中package_index是個u2表,表裡的每個u2值都是常量池索引,並且索引指向的一定是CONSTANT_Package_info常量。mymod模組module-info.class檔案的ModulePackages_attribute屬性如下圖所示:
ModuleMainClass_attribute
ModuleMainClass_attribute屬性記錄模組主類,結構如下所示:
ModuleMainClass_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 main_class_index;
}
其中main_class_index是指向CONSTANT_Class_info常量的索引。mymod模組module-info.class檔案的ModuleMainClass_attribute屬性如下圖所示:
Module_attribute
Module_attribute屬性比較複雜,結構如下所示:
Module_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 module_name_index;
u2 module_flags;
u2 module_version_index;
u2 requires_count;
{ u2 requires_index;
u2 requires_flags;
u2 requires_version_index;
} requires[requires_count];
u2 exports_count;
{ u2 exports_index;
u2 exports_flags;
u2 exports_to_count;
u2 exports_to_index[exports_to_count];
} exports[exports_count];
u2 opens_count;
{ u2 opens_index;
u2 opens_flags;
u2 opens_to_count;
u2 opens_to_index[opens_to_count];
} opens[opens_count];
u2 uses_count;
u2 uses_index[uses_count];
u2 provides_count;
{ u2 provides_index;
u2 provides_with_count;
u2 provides_with_index[provides_with_count];
} provides[provides_count];
}
Module_attribute屬性雖然結構複雜,但其實就是module-info.java檔案中模組定義裡requires、exports、opens、uses和provides語句的直接對映。mymod模組module-info.class檔案的Module_attribute屬性總體如下圖所示:
requires語句對應的部分如下圖所示:
exports語句對應的部分如下圖所示:
opens語句對應的部分如下圖所示:
uses語句對應的部分如下圖所示:
provides語句對應的部分如下圖所示:
廣告
以上Java9在class檔案方面的變動就介紹完了,如果想深入瞭解Java8的class檔案格式,請關注自己動手寫Java虛擬機器 這本書 :)
相關文章
- java class 檔案格式解析Java
- Class 檔案格式詳解
- Java二進位制Class檔案格式解析Java
- 怎樣將class檔案變成.exe檔案?薦
- 【JVM】JVM系列之Class檔案(三)JVM
- Class檔案解析
- java class檔案解析Java
- class與dex檔案
- Java虛擬機器之Class類檔案結構Java虛擬機
- java class檔案詳解Java
- Class類檔案結構
- Java Class檔案詳解Java
- docx是什麼格式的檔案 圖片怎麼變成docx檔案
- 破解class檔案的第一步:深入理解JAVA Class檔案Java
- ClassPlaceholder外掛:動態修改jar包class檔案JAR
- smali 檔案格式
- elf檔案格式
- FastQ檔案格式AST
- Cron檔案格式
- PE檔案格式
- 檔案流下載檔案,zip/其他格式檔案
- 【JVM】深入解析class類檔案JVM
- Jvm之用java解析class檔案JVMJava
- JAVA Class類檔案結構Java
- OT的Thinkphp框架驅動檔案不全Memcached.class.phpPHP框架
- HTTP multipart/form-data格式之檔案上傳HTTPORM
- JPEG格式研究——(2)JPEG檔案格式
- BVH檔案格式解析
- windows文字檔案格式?Windows
- LDS檔案格式分析
- Photoshop檔案格式(轉)
- 如何獲取java執行時動態生成的class檔案?Java
- 檔案同步類SimFileSync.class.phpPHP
- 類檔案結構_class類檔案的的結構
- Office檔案格式突變,促使Java和Office更完美整合(轉)Java
- 配置歸檔位置和檔案格式
- 檔案開啟的格式
- 開啟.ziw格式檔案