在这篇文章中http://java.sun.com/docs/books/tutorial/java/package/usepkgs.html
写入“Apparent Hierarchies of Packages”段落:
“”首先,包看起来是分层的,但它们不是。例如,Java API包括java.awt包,java.awt.color包,java.awt.font包以及许多以java.awt开头的包。但是,java.awt.color包中包含java.awt.color包,java.awt.font包和其他java.awt.xxxx包。 “”
但如果我unjar rt.jar我发现java.awt.color和java.awt.font映射在一个 分层方式:java / awt / color和java / awt / font所以我理解不好或者帖子中有错误吗?
但是,是否可以创建不分层的包?逻辑包名称与phisical包结构不匹配?
答案 0 :(得分:7)
文章继续
导入java.awt。*导入所有 java.awt包中的类型,但是 它不会导入java.awt.color, java.awt.font,或任何其他 java.awt.xxxx包。
所以它只描述了import语句的一般行为:import package.*
从package
导入所有类,但没有子包中的类。
是的,类文件在我们期望的rt.jar中,这只是在java源文件中导入类。
修改强>
是的,该教程增加了一定程度的混淆。
尝试将包理解为共享公共命名空间的类的集合。 java.awt
是名称空间,java.lang
和java.awt.color
是另一个名称空间。现在明白,java.awt
和java.awt.color
名称空间不相关。 java.awt.color
不是java.awt
的“子”命名空间。事实上,Java中没有规则你必须将某些类放在某些“子”包中。如果有一个hierarchie,我希望有一些规则,比如实现必须在接口的'子命名空间'中声明,或者左右。但是没有任何
是的,命名空间到文件系统的实际映射引入了一个文件夹层,其中颜色是awt中的文件夹。这非常实用,否则我们需要在包命名空间和文件系统中类的物理位置之间进行映射。现在我们可以从包命名空间确定位置。这导致了这样的印象,即这个层次结构也适用于包命名空间。
但事实并非如此。这就是教程想要说的内容。
(感谢这个问题,我在思考答案的过程中学到了很多并且理解了很多;)
答案 1 :(得分:7)
您引用的文章解释了下一段中的要点。包的名称用于表示程序员眼中的关系,但在编译器的眼中没有任何关系。正如文章解释的那样导入java.awt.*
不会导入java.awt.font
中的任何类,它们是完全独立的包,在编程语言中没有任何层次关系。要导入java.awt.font
中的所有类,您必须导入java.awt.font.*
并且不导入父包java.awt
或兄弟包中的任何类,如java.awt.color
。
所以尽管程序员之间存在明显的层次关系,但实际上并没有任何语言。要访问给定包中的类,您必须从它们的确切包中导入它们。
如果包实际上是层次结构,那么人们可能会想到会出现这种情况。然而,层次结构仅用于组织代码并向程序员提示一组给定的包将被一起使用。
答案 2 :(得分:3)
教程的含义是Java中没有子包的概念。包可能实际上位于文件系统中的子文件夹中,但这并不意味着它将自动包含在内(请参阅Andreas' answer)。
它也不会为更高级别的包权限提供访问包私有(默认范围)类的类,正如您可能期望的那样,如果存在包层次结构。
答案 3 :(得分:1)
命名方案是层次结构,以及jar文件的内容。
但是,java.awt和java.awt.color之间没有任何关联,也就是说,例如,如果在包 foo 中将类声明为包private(没有修饰符),它可以从 foo 访问,但不能从 foo.bar 访问。
答案 4 :(得分:0)
将层次结构视为文件系统。在Java中,包类似于目录,类就像文件。包旨在包含一组相关的类。当存在逻辑相关的包组时,可以对它们进行命名,使它们显示为更大层次结构的成员。看看上面的java.awt。*示例,我可以在jar1中放置AWT的类。它将具有以下结构:
jar-1
\-java
\-awt
在awt目录中,您将找到声明自己是包java.awt成员的类和接口。
现在我想为awt实现一些字体,但我将它们放在一个单独的jar中:
jar-2
\-java
\-awt
\-fonts
字体目录是我为awt创建的字体的类和接口。
当您使用AWT和我的字体进行编程时,首先必须在CLASSPATH中包含jar-1和jar-2。当您包含这些类时,您不会得到任何关于编译器找到它们的jar的反馈。
//this loads all classes in the java.awt directory
// which happen to come from jar-1
include java.awt.*
如果你想要字体,
//Load all classes in the java.awt.fonts directory
// which happen to come from jar-2
include java.awt.fonts.*
对于编译器和运行时,层次结构看起来像一棵大树。这并不意味着所有类都存在于同一个地方。说过我必须说两点; 1)不建议将同一层次结构中的包分成不同的jar,因为它会让人感到困惑和维护问题,2)将包声明为别人的包结构的扩展是非常糟糕的形式,即使编译器允许你这样做。