Java 9中的"模块本地"访问行为

And*_*niy 13 java access-modifiers java-platform-module-system java-9

由于Jigsaw项目的核心是Java模块系统,因此能够仅限制对特定模块内特定程序元素(类,方法和字段)的访问是很好的.

当模块中的某些元素对于此模块基本上是公共的时,它可能会有所帮助,但不应在此模块外部访问.

所以我说的是"package-local"之后的下一级访问,可以命名为"module-local".

然而,简要介绍Jigsaw规则和早期规范并没有帮助我弄清楚这种功能.更具体地说,Modifier规范不包含任何新元素.

那么在未来的Java 9中还有其他任何可能吗?

Mar*_*old 13

非导出包中的public元素(类,接口,方法或字段)实际上是"模块本地".模块中的所有其他代码都可以访问它,但不能从模块外部访问.

无法在导出的包中声明模块本地元素.甲public导出的包的元件是可访问的从模块的外部,一个包专用元件仍然是包专用,而且也这两种模式之间没有元件级的访问模式.我们可以定义一个新的这种模式,但我们已经看到它很少引人注目的用例,而且,在JVM中以比导出的包更精细的粒度实现模块化访问控制会带来显着的性能成本.


Nic*_*lai 6

简答

当模块中的某些元素对于此模块基本上是公共的时,它可能会有所帮助,但不应在此模块外部访问.

这是不可能的.(仅使用模块系统的方法 - 有一种解决方法.)

答案很长

解释在" 可访问性 "一词中:

Java编译器和虚拟机考虑在一个包中的公共类型在一个模块中是可访问由其他一些模块代码仅当第一模块是由所述第二模块可读的,在上面定义的意义,且第一模块的出口该包.[...]

以这种方式无法访问的模块边界引用的类型不可用,就像私有方法或字段不可用一样:任何使用它的尝试都将导致编译器报告错误,或者IllegalAccessError抛出错误Java虚拟机,或IllegalAccessException反射运行时API抛出的虚拟机.[...]

如果在这种意义上,如果其封闭类型是可访问的,并且成员本身的声明也允许访问,则可以访问跨模块边界引用的方法或字段.

虽然编译器/ JVM认为可以访问包的类型和方式有多种不同的方式,但是没有其他机制适用.它的成员和Jigsaw之前一样容易接近.

这意味着无法在模块中(可能需要public)显示可访问类型的成员,但不能在其外部(因为可访问类型的公共成员是可访问的).

解决方法

那么在未来的Java 9中还有其他任何可能吗?

是.:)

您可以Global在导出的包中具有公共接口,该接口定义要导出到世界的方法.然后让接口或类Local扩展Global并添加所需的所有成员.关键是,Local必须不能在导出的包!

现在,如果你的模块的API只返回Global-s但从不接受它们作为方法参数,那么你很高兴.只要确保你在内部总是使用 - 也许可以施放 - Local.

如果你也接受Global-s,你必须清楚地记录这些只能是你的API返回的实例(即不允许用户创建自己的实现).这可能听起来令人望而却步,但如果您认真考虑原始请求,它将具有相同的特征.