Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
&引用;“本地模块”;Java9中的访问行为_Java_Access Modifiers_Java 9_Java Platform Module System - Fatal编程技术网

&引用;“本地模块”;Java9中的访问行为

&引用;“本地模块”;Java9中的访问行为,java,access-modifiers,java-9,java-platform-module-system,Java,Access Modifiers,Java 9,Java Platform Module System,由于Jigsaw项目的核心是Java模块系统,因此最好能够仅在特定模块内限制对特定程序元素(类、方法和字段)的访问 当模块中的某些元素基本上是此模块的公共元素,但不应在该模块之外访问时,这可能会有所帮助 所以我说的是“包本地”之后的下一个访问级别,可以命名为“模块本地” 然而,对早期规范的简要介绍并不能帮助我找到此类功能。更具体地说,它不包含任何新元素 那么,在未来的Java 9中,是否还有其他可能做到这一点呢?简短回答 当模块中的某些元素基本上是此模块的公共元素,但不应在该模块之外访问时,这可

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

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

所以我说的是“包本地”之后的下一个访问级别,可以命名为“模块本地”

然而,对早期规范的简要介绍并不能帮助我找到此类功能。更具体地说,它不包含任何新元素

那么,在未来的Java 9中,是否还有其他可能做到这一点呢?

简短回答 当模块中的某些元素基本上是此模块的公共元素,但不应在该模块之外访问时,这可能会有所帮助

这是不可能的。(仅通过模块系统-有一个解决方法。)

长话短说 解释在以下术语范围内:

java编译器和虚拟机考虑在一个模块中的一个包中的公共类型,在另一个模块中只有当第一个模块可以在第二个模块中读取时,在上面定义的意义上,第一个模块导出该包,才能访问该模块。[……]

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

如果模块边界上引用的方法或字段的封闭类型是可访问的(从这个意义上讲),并且如果成员本身的声明也允许访问,则可以访问该方法或字段

虽然有不同的方法可以确切地将包导出给谁以及如何导出包,但一旦编译器/JVM认为某个类型是可访问的,就不会应用任何其他机制。其成员与Jigsaw之前一样容易访问

这意味着无法使可访问类型的成员在模块内可见(这需要
public
),但不能在模块外可见(因为可访问类型的公共成员是可访问的)

变通办法 那么,在未来的Java9中是否还有其他可能做到这一点呢

是。:)

您可以在导出的包中拥有一个公共接口
Global
,该包定义了要导出到世界的方法。然后创建一个接口或类
Local
extend
Global
,并添加所有需要的成员。关键是
Local
不能在导出包中

现在,如果模块的API只返回
Global
-s,但从不接受它们作为方法参数,那么就可以开始了。只需确保您在内部始终使用-并且可能转换为-
Local


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

A
public
元素(即类、接口、方法或字段)在 非导出包实际上是“模块本地”的 可访问模块中的所有其他代码,但不能从外部访问 模块

无法在导出的包中声明模块本地元素。 导出包的
public
元素可以从外部访问 模块中,包私有元素仍然是包私有的,并且 这两种模式之间没有元素级访问模式。我们可以定义一个
这是一种新的模式,但我们很少看到令人信服的使用案例,
此外,在JVM中以粒度实现模块化访问控制 比导出的包更精细将带来显著的性能
成本。

据我所知,默认情况下,模块已锁定。你必须明确地导出一些东西,使它们能够从外部得到满足。和。我是不是误解了你的意思?据我所知,只有导出的软件包在模块外可用。例如,请参见。@Gimby您说得很对:可以导出特定的包。但是方法和领域呢?是的,我想你对我的问题理解得很对。恐怕出口机制是在包装层面上运作的。引用上面链接的sotms:因此,即使类型被声明为公共类型,如果其包没有在其模块的声明中导出,则只有该模块中的代码才能访问该类型。如果模块边界上引用的方法或字段的封闭类型是可访问的(从这个意义上讲),并且如果成员本身的声明也允许访问,则可以访问该方法或字段。“我不想写任何东西,因为它还没有发布,也无法判断当前的功能是否会发布。但是您可以关注关于jigsaw-dev的讨论。例如,请参见“但是我们很少看到它的引人注目的用例”——我敢肯定,Java世界中没有。你找别的地方了吗?在构建了一个不平凡的Swift之后,对我来说,缺少
内部
会破坏模块在建模/设计方面的大部分潜在优势。我们的用例:具有加密密钥的
用户
“资源”。虽然
User
是公共的,但密钥应该是模块专用的,但不一定是包专用的。我想你必须通过只公开接口来解决这个问题,但是你必须以你意想不到的方式处理用户可能实现它们的问题。子类化也会出现类似的问题<代码>最终版
防止子类无处不在,