Java9之class文件格式变动
2017-10-19 16:57
204 查看
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文件格式
- 解析Java的Class文件格式——解析魔数和版本号(一)
- JAVA的class文件格式例解
- java class文件格式解析
- Java 的 Class 文件格式——解析魔数和版本号
- 深入理解Java Class文件格式(七)
- 深入理解Java Class文件格式(一)
- 深入理解Java Class文件格式(八)
- 解读Java Class文件格式
- 深入理解Java Class文件格式(五)
- 深入理解Java Class文件格式(三)
- Java二进制Class文件格式解析
- 解析Java的Class文件格式——解析魔数和版本号
- JAVA class文件格式
- 深入理解Java Class文件格式(四)
- Java Class文件深度格式解析
- 深入理解Java Class文件格式(二)