我在Stack Overflow和其他地方看到过许多帖子,声称Java没有子包的概念。 经常指出的一件事是包与其"子包"之间缺乏任何特殊的访问关系。 例如,如果不向所有其他包公开一个类或方法,就无法向com.example.subpackage
中的类公开com.example
类或方法(反之亦然)。 然而,尽管有这些断言,我看到Java语言规范确实在第7章中定义了"子包"的概念。包和模块。
可能包含自己的编译单元和子包)。
因此,什么是 Java 中的子包,它有什么作用?
子包的存在是为了方便组织代码。 它们对类/接口命名施加了限制(一个类不能具有与子包相同的完全限定名),但在其他方面与两个不相关的包没有什么不同。
Java 语言规范在第 7.1 节 "包成员"中定义了哪些子包。
子包是直接嵌套在另一个包中的任何包。 例如,com.example.subpackage
是com.example
的子包:
的成员是其子包以及在包的所有编译单元中声明的所有顶级类类型和顶级接口类型。
例如,在 Java SE Platform API 中:
- 包
java
有子包awt
、applet
、io
、lang
、net
和util
,但没有编译单元。- 包
java.awt
有一个名为image
的子包,以及许多包含类和接口类型声明的编译单元。
子包在子包和包中的类/接口之间强制实施命名约束。 也就是说,子包和类/接口不能在同一包中共享相同的名称:
包不能包含两个同名的成员,否则会产生编译时错误。
以下是一些示例:
- 因为包
java.awt
有一个子包image
,所以它不能(也不)包含名为image
的类或接口类型的声明。- 如果存在名为
mouse
的包,并且该包中的成员类型Button
(然后可能称为mouse.Button
),则不能有任何具有完全限定名的包mouse.Button
或mouse.Button.Click
。- 如果
com.nighthacks.java.jag
是类型的完全限定名,则不能有任何包的完全限定名为com.nighthacks.java.jag
或com.nighthacks.java.jag.scrabble
。
子包概念主要出于组织目的而存在。 对名称冲突的限制是该语言赋予子包的唯一意义:
包的分层命名结构旨在便于以常规方式组织相关包,但除了禁止包具有与该包中声明的顶级类型具有相同简单名称的子包之外,其本身没有任何意义。
例如,名为
oliver
的包与另一个名为oliver.twist
的包之间或名为evelyn.wood
和evelyn.waugh
的包之间没有特殊的访问关系。也就是说,与任何其他包中的代码相比,名为oliver.twist
的包中的代码对包oliver
中声明的类型没有更好的访问权限。