Java 9中的开放模块是什么?如何使用它?

Java 9中的开放模块是什么?如何使用它?,java,java-9,java-module,module-info,Java,Java 9,Java Module,Module Info,前面有open关键字的模块与没有关键字的模块有什么区别?例如: open module foo { } module foo { } 为了提供对模块的反射访问,Java9引入了open关键字 您可以通过在模块声明中使用open关键字来创建打开的模块 开放模块允许其他模块对其所有包进行反射访问 例如,如果您想使用一些严重依赖反射的框架,如Spring、Hibernate等,可以使用此关键字为其启用反射访问 您可以使用包声明中的OPENES语句为模块的指定包启用反射访问: module foo

前面有
open
关键字的模块与没有关键字的模块有什么区别?例如:

open module foo {
}

module foo {
}

为了提供对模块的反射访问,Java9引入了open关键字

您可以通过在模块声明中使用open关键字来创建打开的模块

开放模块允许其他模块对其所有包进行反射访问

例如,如果您想使用一些严重依赖反射的框架,如Spring、Hibernate等,可以使用此关键字为其启用反射访问

您可以使用包声明中的OPENES语句为模块的指定包启用反射访问:

module foo {
    opens com.example.bar;
}
open module foo {
}
或者在模块声明中使用open关键字:

module foo {
    opens com.example.bar;
}
open module foo {
}
但请记住,不能将它们组合在一起:

open module foo {
    opens com.example.bar;
}
具有编译时错误的结果


希望能有所帮助。

了解一下相关指令的背景知识。破坏封装部分中的状态

有时有必要违反访问控制边界 由模块系统定义,并由编译器和虚拟机执行 机器,以便允许一个模块访问一些未报告的 其他模块的类型。这可能是可取的,例如:。, 启用内部类型的白盒测试,或公开不受支持的 将内部API添加到依赖它们的代码中。这个
--addexports
选项可以在编译时和运行时使用

命令行选项相当于,例如:-

module java.logging {
    exports java.util.logging;
}
module jdk.unsupported  {
   opens sun.misc; 
}
--add exports
选项允许访问指定包的公共类型


尽管此后,

有时有必要更进一步,让所有人都能访问 通过核心的setAccessible方法创建非公共元素 反射API。
--add opens
选项可在运行时用于 这样做

此命令行选项相当于,例如:-

module java.logging {
    exports java.util.logging;
}
module jdk.unsupported  {
   opens sun.misc; 
}

相比之下,普通命名模块通过模块声明显式定义为:-

module foo { }
这些被称为。显式模块可以在包上使用如上所述的指令,例如导出/
打开
包,以提供对其各自公共成员和类的反射访问


另一方面,模块是

未声明任何打开的包但生成的模块是 视为所有包裹都已打开


这样,它在运行时授予对所有模块包中的类型的访问权限,就像导出所有包一样,这意味着字节码或反射可用于访问所有包中每个包的类或成员。带有
setAccessible
MethodHandles.privateLookupIn
的反射API允许深度反射,因此简而言之您可以反射所有包中所有类的所有成员。这也很好地解释了编译器不允许

的原因。根据定义,打开的模块不会打开任何包,因为默认情况下,所有的包都被认为是在生成的模块中打开的。:)对于每个包,将“openmodule”与opens指令结合起来是没有逻辑意义的。开放模块只是打开其所有包的模块的简写。