理解Java 9的open module(公开模块)

模块化是Java 9新增的一个很重要且影响代码结构的特性。

分类

根据外部代码在编译时和运行时对模块的访问权限不同分为:常规模块(normal module)和公开模块(open module)。

编译时访问比较容易理解,即代码能否显式直接使用模块里的类型,没有权限访问,编译时报错。在运行时访问模块代码是指使用Java里的Core Reflection API,反射访问。

在一些框架里如Spring Framework,在运行时常常会使用反射机制访问代码。

常规模块

声明常规模块在module前没有关键字open。

module com.example {

}

外部代码访问常规模块,不管是在编译时(compile time)还是在运行时(runtime)都只授权访问模块明确导出的包里的类型。

module com.example {
  exports com.example.service;
}

在这个示例里,外部代码只能访问模块com.example里的com.example.service类型,对于其他没有导出的包不能访问。

另外,即使是模块导出的包,也并不是包里的所有类型都能访问,外部代码只能访问public和protected类型,以及这里类型里的public和protected成员变量和方法。

公开模块

声明公开模块在module前添加关键词open。

open module com.example {

}

外部代码访问公开模块,在编译时只授权访问模块明确导出的包里的类型。而在运行时则能够访问模块里的所有包类型。

open module com.example {
  exports com.example.service;
}

与常规模块一样,在编译时,外部代码只能访问模块导出的com.example.service里的类型,且也只能访问包里的public和protected类型,以及这些类型里的public和protected成员。

在运行时,外部代码则可以访问公开模块的所有包里的类型以及这些类型的成员,不受类型是否为public或protected控制。

opens指令

但有时不需要对模块的所有包都公开,这种情况可以在module的声明体里使用opens指令。

module com.example {
  exports com.example.service;
  opens com.example.service.spi;
}

对于使用opens公开的包,在运行时,外部代码对这些包里的所有类型都是可以使用反射机制访问到的。

注意:opens指令只能在常规模块中使用,不能用在公开模块里。这是比较容易理解的,因为在公开模块里所有的包都是公开的。

版权声明:著作权归作者所有。

相关推荐

Java 9的Process和ProcessHandler

Java 9给Process API引入了多种改进,其中新增了ProcessHandler类,它提供了进程相关的信息,如pid,父进程,子进程,进程开始时间以及累计cpu时间等。这里使用Java 9的jshell简单演示下Process的使用:jshell> Process p = new ProcessBuil

理解Java的数字溢出

Java各个数字类型所占的存储空间:整型byte:1字节,1*8bit,取值范围-128~127short:2字节,2*8bit,取值范围-32768~32767int:4字节,4*8bit,取值范围-2147483648~2147483647long:8字节,8*8bit,取值访问-2^64~2^64-1浮点型float:4字节,4*8bitdouble:8字节,8*8bitchar类型java

[译]代码优先的Java 9模块系统教程(二)

服务监控(ServiceMonitor)让我们来想象一个提供娱乐服务的网络,可能是社交网络或者是视频网络。我们希望监控这些服务,以确定系统的健康状况,并且在发生问题时能够发现,而不是客户报告。 这就是ServiceMonitor示例程序所要做的:监视这些服务(另一个惊喜)。幸运的是,服务已经收集了我们想要的数据,ServiceMonitor所需要做的就是定期查询。 不幸的是,并

Angular CLI:配置webpack热模块替换hmr(Hot Module Replacement)

热模块替换(Hot Module Replacement)是Webpack的特性,它可以让我们在调试时不需要重新构建就可以更新代码到正在运行的应用。Angular CLI需要做一些设置就可以使用webpack的热模块替换功能。添加依赖hrm依赖于@angularclass/hmr,安装@angularclass/hmr到dev-dependency$ npm

[译]代码优先的Java 9模块系统教程(一)

Java平台模块系统(JPMS)将模块化带入Java和JVM,并改变了我们在大型应用中的编程方式。 为了充分利用它,我们需要很好地了解,第一步是学习基础知识。 在本教程中,我首先向你展示一个简单的Hello World示例,然后我们用Java 9将一个现有的demo程序模块化。我们将创建模块声明(module-info。java),使用模块路径来编译,打包,

Java 9模块声明中requires and requires transitive的区别

可读性(Readability)首先要理解模块的可读性module bar{     requires drink; } bar requires drink意味着:bar模块强制要求存在drink模块,这称为可靠配置。bar模块可以读入drink模块的文件,这称为可读性。bar模块可以访问drink模块的代码,这称为