java 模块化
java9出了模块,作为一名主要用java的程序员,所以要提前学习,保持一颗好学的心.
1.创建模块
新建java project com.horstmann.greet,eclipse新版会提示是否要创建模块,
,如果在此输入模块名字的话就会生成一个module-info.java类,是模块的描述信息类,主要包含以下内容
到此一个模块就创建好了,如果没有在创建的时候输入模块,也可以自己新建module-info.java类来创建模块.
2. 暴露模块
我们创建一个接口
package com.horstmann.greet; public interface Greeter { static Greeter newInstance() { return new com.horstmann.greet.internal.GreeterImpl(); } String greet(String subject); }
和它的实现类
package com.horstmann.greet.internal; import com.horstmann.greet.Greeter; public class GreeterImpl implements Greeter { @Override public String greet(String subject) { // TODO Auto-generated method stub return "Hello, " + subject + "!"; } }
目录结构如下
一般来说都会暴露模块的接口,而不是实现类,类似于es6中的模块,我们直接exports包即可
module com.horstmann.greet {
exports com.horstmann.greet;
}
这样其他模块就可以引用即可
3.引用暴露的模块
新建模块 v2ch09.exportedpkg
创建类HelloWorld
在eclipse中右键属性引入刚刚的模块
编辑module-info.java即可引入导出的类
module v2ch09.exportedpkg {
requires com.horstmann.greet;
requires hellomod.test;
}
public class HelloWorld { public static void main(String[] args) { Greeter greeter = Greeter.newInstance(); System.out.println(greeter.greet("Modular World")); } }
直接运行helloworld类,即可看到结果
通过exports和requires,我们可以在module-info中对模块的权限进行控制,需要哪些模块,不需要哪些模块,非常方便.
4.模块和反射
模块不能通过反射访问私有属性比如:
package hellomod.test; public class ReflectTest { private Integer name; public ReflectTest(Integer name) { super(); this.name = name; } }
我在另一个模块通过反射访问name,会报错
ReflectTest reflectTest = new ReflectTest(123); Field field = reflectTest.getClass().getDeclaredField("name"); System.out.println(field.getInt(reflectTest));
解决: 在要访问的模块中添加open关键词即可
open module hellomod.test{
exports hellomod.test;
}
如图 我们在module 前面添加 open即可
或者添加exports和opens关键词
module hellomod.test{
exports hellomod.test;
opens hellomod.test;
}
即可开放反射访问权限
5.自动模块和不具名模块
自动模块: 就是把jar文件放到模块路径上的模块. 为了改造以前的方式成模块,jar文件直接可以放到模块路径上成为一个新的模块
所有包都导出,包含其他所有模块
不具名模块: 不在模块路径中的类组成的模块.
可以访问其他模块,但是不能被其他模块访问