如果 Java 子包不提供特殊的访问关系,它们会做啥?

Posted

技术标签:

【中文标题】如果 Java 子包不提供特殊的访问关系,它们会做啥?【英文标题】:What do Java subpackages do, given that they don't provide a special access relationship?如果 Java 子包不提供特殊的访问关系,它们会做什么? 【发布时间】:2020-09-22 21:43:22 【问题描述】:

我在 Stack Overflow 和其他地方看到很多帖子断言 Java 没有子包的概念。经常指出的一件事是包和它的“子包”之间缺乏任何特殊的访问关系。例如,没有办法将com.example 中的类或方法暴露给com.example.subpackage 中的类(反之亦然)而不将其暴露给所有其他包。然而,尽管有这些断言,我看到Java Language Specification 确实在Chapter 7. Packages and Modules 中定义了“子包”的概念。

包的成员是类和接口类型,在包的编译单元中声明,子包可以包含自己的编译单元和子包。

因此,Java 中的子包是什​​么,它有什么作用?

【问题讨论】:

【参考方案1】:

存在子包以方便地组织代码。它们对类/接口命名施加了限制(一个类不能与子包具有相同的完全限定名),但在其他方面与两个不相关的包没有什么不同。

Java 语言规范在第 7.1 节 Package Members 中定义了哪些子包。

子包是直接嵌套在另一个包中的任何包。比如com.example.subpackagecom.example的子包:

包的成员是它的子包以及在包的所有编译单元中声明的所有***类类型和***接口类型。

例如,在 Java SE Platform API 中:

java 有子包awtappletiolangnetutil,但没有编译单元。 java.awt 有一个名为image 的子包,以及一些包含类和接口类型声明的编译单元。

子包在包内的子包和类/接口之间强制执行命名约束。即,一个子包和一个类/接口不能在同一个包内同名:

一个包不能包含两个同名成员,否则会导致编译时出错。

这里有一些例子:

因为包java.awt 有一个子包image,它不能(也不)包含一个名为image 的类或接口类型的声明。 如果有一个名为 mouse 的包和该包中的成员类型 Button(然后可能被称为 mouse.Button),则不能有任何具有完全限定名称 @ 的包987654339@或mouse.Button.Click 如果com.nighthacks.java.jag 是一个类型的完全限定名,则不能有任何完全限定名是com.nighthacks.java.jagcom.nighthacks.java.jag.scrabble 的包。

子包的概念主要是为了组织目的而存在的。对名称冲突的限制是唯一语言赋予子包的意义:

包的分层命名结构旨在方便以常规方式组织相关包,但除了禁止包具有与声明的***类型相同的简单名称的子包外,其本身没有任何意义在那个包里。

例如,一个名为oliver 的包与另一个名为oliver.twist 的包之间或名为evelyn.woodevelyn.waugh 的包之间没有特殊的访问关系。也就是说,oliver.twist 包中的代码对oliver 包中声明的类型的访问没有任何其他包中的代码更好。

【讨论】:

以上是关于如果 Java 子包不提供特殊的访问关系,它们会做啥?的主要内容,如果未能解决你的问题,请参考以下文章

Java中包和子包的关系

使用eclipse创建包以及子包

如何将java包和子包作为程序运行?

Unity打Android包不卡,但是在打IOS包后卡

java中,引用另一个包中的类做父类时,显示程序包不存在怎么办

java 程序包systerm不存在