如果 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.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
),则不能有任何具有完全限定名称 @ 的包987654339@或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
包中声明的类型的访问没有任何其他包中的代码更好。
【讨论】:
以上是关于如果 Java 子包不提供特殊的访问关系,它们会做啥?的主要内容,如果未能解决你的问题,请参考以下文章