Java 9引入了一些新的模块系统特性,包括opens和exports,主要是为了更好地实现模块化开发,提高代码安全性。
opens和exports的概念
- opens:可以让模块中的某个包在运行时可以被其他模块反射调用。
- exports:可以让模块中的某个包在编译时和运行时都可以被其他模块访问和使用。
区分opens和exports的攻略
- 在module-info.java文件中使用opens指令来打开模块中某个包的反射权限,使用exports指令来公开模块中某个包的使用权限。可以使用“模块名/包名”的方式指定需要打开或公开的包,也可以使用通配符来指定。
例如,在一个名为com.example.foo的模块中,如果要开放com.example.bar包的反射权限,可以在module-info.java文件中添加如下代码:
opens com.example.bar to module1, module2;
这样,其他模块module1和module2就可以使用反射来访问com.example.bar包中的类、变量和方法了。
而如果要公开com.example.baz包的使用权限,可以在module-info.java中添加如下代码:
exports com.example.baz to module1, module2;
这样,其他模块module1和module2就可以直接使用com.example.baz包中的类、变量和方法了。
- 可以使用jdeps工具来查看模块之间的依赖关系和可能存在的问题。例如,可以使用下面的命令来查看某个模块的依赖情况:
jdeps --module-path <path-to-modules> --list-deps <module-name>
其中,--module-path指定了模块路径,
示例1:opens
假设有两个模块:moduleA和moduleB,其中moduleA定义了一个类MyClass,可以使用反射调用其中的方法、变量等。而moduleB需要使用moduleA中MyClass类中的某个方法,这时就需要在moduleA中打开MyClass的反射权限。
首先,在moduleA的module-info.java文件中添加如下代码:
opens com.example.common.model to moduleB;
这样,就在moduleA中开放了com.example.common.model包的反射权限,同时指定moduleB可以访问。
然后,在moduleB中使用反射来调用moduleA中MyClass类的test方法,代码如下:
Class<?> clazz = Class.forName("com.example.common.model.MyClass");
Method method = clazz.getDeclaredMethod("test");
method.invoke(null);
这样,moduleB就可以成功调用moduleA中MyClass类的test方法了。
示例2:exports
本例中有两个模块:moduleA和moduleB,其中moduleA定义了一个类MyClass,而moduleB需要使用MyClass类中的某个方法,这时就需要在moduleA中公开MyClass类的使用权限。
首先,在moduleA的module-info.java文件中添加如下代码:
exports com.example.common.model to moduleB;
这样,就在moduleA中公开了com.example.common.model包的使用权限,同时指定moduleB可以访问。
然后,在moduleB中正常使用MyClass类的test方法,代码如下:
MyClass myClass = new MyClass();
myClass.test();
这样,moduleB就可以成功访问moduleA中MyClass类的test方法了。
总的来说,使用opens和exports都是为了实现模块化开发,提高代码安全性。开发者需要根据实际的需求来选择具体的使用方式。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java9区分opens与exports - Python技术站