Java --add-opens java.base/java.lang=ALL-UNNAMED
在Java 9及以后的版本中,引入了模块化系统,它允许将代码和资源划分为多个模块以提高代码的可维护性和安全性。然而,由于模块的隔离性,某些代码可能无法在模块之间进行正常的交互。这时,我们可以使用Java --add-opens
选项来解决此类问题。
什么是--add-opens
选项?
--add-opens
是Java 9引入的一个命令行选项,它允许我们在模块之间打开指定的包,以便其他模块可以访问这些包中的类和成员。特别地,--add-opens
选项用于在指定的模块中打开指定的包,并将其对所有模块的访问权限设置为“ALL-UNNAMED”,这意味着所有模块都可以访问这些包。
如何使用--add-opens
选项?
我们通过一个简单的代码示例来演示如何使用--add-opens
选项。假设我们有两个模块:com.example.moduleA
和com.example.moduleB
,并且moduleA
需要访问moduleB
中的一个受限包com.example.moduleB.internal
。在正常情况下,由于模块的隔离性,moduleA
无法访问com.example.moduleB.internal
包中的类和成员。
让我们先来创建moduleB
模块。我们创建一个名为com.example.moduleB
的文件夹,并在该文件夹中创建一个模块描述文件module-info.java
,其内容如下:
module com.example.moduleB { exports com.example.moduleB; // 公开com.example.moduleB包 // 不公开com.example.moduleB.internal包}
接下来,我们在com.example.moduleB
包中创建一个简单的类MyClass
,其代码如下:
package com.example.moduleB;public class MyClass { public void sayHello() { System.out.println("Hello from moduleB!"); }}
现在,我们创建moduleA
模块。同样地,我们创建一个名为com.example.moduleA
的文件夹,并在该文件夹中创建一个模块描述文件module-info.java
,其内容如下:
module com.example.moduleA { // 不公开任何包}
我们在com.example.moduleA
模块中创建一个类Main
,尝试访问moduleB
模块中的MyClass
类,其代码如下:
package com.example.moduleA;import com.example.moduleB.MyClass;public class Main { public static void main(String[] args) { MyClass myClass = new MyClass(); myClass.sayHello(); }}
如果我们尝试编译并运行上述代码,将会得到一个编译错误,提示无法访问com.example.moduleB.internal
包。
为了解决这个问题,我们可以使用--add-opens
选项。我们可以在运行moduleA
模块时,使用以下命令行参数来打开moduleB
模块中的com.example.moduleB.internal
包:
java --add-opens com.example.moduleB/com.example.moduleB.internal=com.example.moduleA -m com.example.moduleA/com.example.moduleA.Main
通过上述命令行参数,我们将moduleB
模块中的com.example.moduleB.internal
包对moduleA
模块的访问权限设置为“ALL-UNNAMED”。现在,我们再次编译并运行Main
类,将会成功输出Hello from moduleB!
。
总结
--add-opens
选项是Java 9引入的一个命令行选项,用于打开模块之间的包,以便其他模块可以访问这些包中的类和成员。通过使用--add-opens
选项,我们可以解决由于模块的隔离性而导致的访问限制问题。但是,应该注意的是,--add-opens
选项可能会降低代码的安全性,因为它打开了