问题描述
我在Stack Overflow上看到了许多帖子,其他地方都断言Java没有子包的概念。经常指出的一件事是,包与其“子包”之间没有任何特殊的访问关系。例如,无法将com.example
中的类或方法公开给com.example.subpackage
中的类(反之亦然),而不将其公开给所有其他包。但是,尽管有这些断言,但我发现Java Language Specification实际上在Chapter 7. Packages and Modules中定义了“子包”的概念。
包的成员是类和接口类型,它们是在包的编译单元中声明的;子包是子包,其中可能包含它们自己的编译单元和子包。
因此,Java中的子包是什么?它有什么作用?
解决方法
Java语言规范在第7.1节Package Members中定义了哪些子包。
子包是直接嵌套在另一个包中的任何包。例如,com.example.subpackage
是com.example
的子包:
包的成员是其子包,并且在包的所有编译单元中声明了所有顶级类类型和顶级接口类型。
例如,在Java SE Platform API中:
- 包
java
具有子包awt
,applet
,io
,lang
,net
和{{1} },但没有编译单元。- 软件包
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
的程序包。
主要出于组织目的而存在子包概念。对名称冲突的限制是该语言赋予子包的 only 含义:
包的分层命名结构旨在方便以常规方式组织相关的包,但除禁止具有与声明的顶级类型具有相同简单名称的子包的包外,其本身没有其他意义。在那个包装中。
例如,在名为
com.nighthacks.java.jag.scrabble
的程序包和名为oliver
的另一个程序包之间,或在名为oliver.twist
和evelyn.wood
的程序包之间没有特殊的访问关系。也就是说,与其他任何软件包中的代码相比,名为evelyn.waugh
的软件包中的代码无法更好地访问在软件包oliver.twist
中声明的类型。
总而言之,存在子程序包以允许方便地组织代码。它们对类/接口命名施加了限制(一个类不能具有与子包相同的完全限定名称),但在其他方面与两个不相关的包没有什么不同。