深入理解JVM(③)Java模块化系统

JDK9引入的Java模块化系统(Java Platform Module System ,JPMS)是 对Java技术的一次重要升级,除了像之前JAR包哪有充当代码的容器之外,还包括:

依赖其他模块的列表。

导出的包列表,即其他模块可以使用的列表。

开放的包列表,即其他模块可反射访问模块的列表。

使用的服务列表。

提供服务的实现列表。

模块化系统

可配置的封装隔离机制解决了原来类路径上跨文件的public类的可访问性的问题。public类型不再意味着所有地方代码都可以访问它们,未导出未开放的类是不能够被外部使用。

举例说明:

新创建一个maven工程,并创建两个module。

在这里插入图片描述

将每个module的Language level 和 SDK 设置成JDK9

在这里插入图片描述

在这里插入图片描述

然后在每个module的顶层目录中创建module-info.java

在这里插入图片描述

在ExampleOne中创建两个不同package下的类,ExampleFirst和ExampleOne。

package com.jimoer.jdkmoduleOne.test; public class ExampleFirst { private int id; private String name; private String sex; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public String toString() { return "ExampleFirst{" + "id=" + id + ",\'' + ", sex='" + sex + '\'' + '}'; } } package com.jimoer.jdkmoduleOne; public class ExampleOne { private int id; private String name; private String arg; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getArg() { return arg; } public void setArg(String arg) { this.arg = arg; } @Override public String toString() { return "ExampleOne{" + "id=" + id + ",\'' + ", arg='" + arg + '\'' + '}'; } }

然后在ExampleOne的module-info.java中声明导出包的路径。

module exampleOne { // 导出包路径 exports com.jimoer.jdkmoduleOne.test; }

在ExampleTwo中声明requires为引入包

module exampleTwo { requires exampleOne; }

然后在ExampleTwo中使用ExampleOne中的类

ublic class ExampleTwo { public static void main(String[] args) { ExampleFirst first = new ExampleFirst(); first.setId(1); first.setName("余欢水"); first.setSex("男"); System.out.println(first); } }

运行结果:

ExampleFirst{id=1,, sex='男'}

但是当在ExampleTwo中引用ExampleOne中非导出包下的类时就会编译出错。

在这里插入图片描述


如上图提示,所有不被导出的包默认都被封装在模块里面。

模块的兼容性

为了使可配置的封装隔离机制能够兼容传统的类路径查找机制,JDK9提出了与“类路径”(ClassPath)相对应的“模块路径”(ModulePath)的概念。只要放在类路径上的JAR文件,都会被当作传统的JAR包来对待;相应地,只要放在模块路径上的JAR文件,即使没有使用JMOD后缀,甚至不包含module-info.class文件,也仍然会被当作一个模块来对待。

为了保证Java应用升级到JDK9之后依然使用传统的类路径,不会受到影响,制定了三条规则来保证兼容性。

JAR文件在类路径的访问规则:所有类路径下的JAR文件及其他资源文件,都被视为自动打包在一个匿名模块(Unnamed Module)里,这个匿名模块几乎是没有任何隔离的,它可以看到和使用类路径上所有的包、JDK模块中所有的导出包,以及模块路径是哪个所有模块中导出的包。

模块在模块路径的访问规则:模块路径下的具名模块(Named Module)只能访问到她依赖定义中列明依赖的模块和包,匿名模块里所有的内容对具名模块来说都是不可见的,即具名模块看不见传统JAR包的内容。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfjfy.html