【问题标题】:Apparent Hierarchies of Packages包的表观层次结构
【发布时间】:2010-12-18 08:33:26
【问题描述】:

在这个帖子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.font 包和其他 java.awt.xxxx 包不包含在 java.awt 包中。 ""

但如果我解压缩 rt.jar,我会发现 java.awt.color 和 java.awt.font 被映射到一个 分层方式:java/awt/color 和 java/awt/font 所以我理解不好还是在那篇文章中有错误?

但是可以创建非分层包吗?与物理包结构不匹配的逻辑包名称?

【问题讨论】:

    标签: java packages


    【解决方案1】:

    文章继续

    导入 java.awt.* 会导入所有 java.awt 包中的类型,但是 它不导入 java.awt.color, java.awt.font 或任何其他 java.awt.xxxx 包。

    所以它只是描述了 import 语句的一般行为:import package.*package 导入所有类,但不从子包中导入类。

    是的,类文件在 rt.jar 中正是我们期望的位置,这只是关于在 java 源文件中导入类。

    编辑

    是的,它的教程增加了一定程度的混乱。

    尝试将包理解为共享公共命名空间的类的集合。 java.awt 是一个命名空间,java.langjava.awt.color 是另一个命名空间。现在明白了,java.awtjava.awt.color 命名空间是不相关的。 java.awt.color 不是 java.awt 的“子”命名空间。事实上,Java 中没有规定必须将某些类放在某些“子”包中。如果有层次结构,我希望一些规则,如实现必须在接口的“子命名空间”中声明,等等。但是没有

    是的,命名空间到文件系统的实际映射引入了一个文件夹层次结构,其中颜色是 awt 中的一个文件夹。这非常实用,否则我们需要包命名空间和文件系统中类的物理位置之间的映射。现在我们可以从包命名空间中确定位置。这给人的印象是,这种层次结构也适用于包命名空间。

    但事实并非如此。这就是教程想要表达的意思。

    (谢谢你的问题,我在思考答案的同时学到了很多东西;))

    【讨论】:

    • 是的,但该段落说““起初,包似乎是分层的,但实际上不是”,但它们在并行文件系统结构中是分层的,因此颜色包包含在 java.awt 中包。在第二段之后说另一件事......
    • 对评论的反应很大,请查看我最近在答案中的编辑
    • 在我由教程给出的接收信息具有误导性,引用:“起初,包似乎是分层的,但它们不是”。它们在物理文件和文件文件夹方面,在指定包的“位置”方面。我认为正确的解释可能是,import 语句中没有递归机制,它导入类。
    【解决方案2】:

    教程的意思是Java中没有子包的概念。一个包可能在物理上位于文件系统的子文件夹中,但这并不意味着它会被自动包含(参见Andreas' answer)。

    它也不授予更高级别包中的类访问包私有(默认范围)类的权限,如果存在包层次结构,您可能会期望。

    【讨论】:

      【解决方案3】:

      命名方案分层的,jar文件的内容也是如此。

      但是,java.awt 和 java.awt.color 之间没有任何联系,也就是说,例如,如果你在包 foo 中将一个类声明为包私有(没有修饰符),它可以从 foo 访问,但不能从 foo.bar 访问。

      【讨论】:

        【解决方案4】:

        您引用的文章解释了下一段中的要点。包的名称用于指示程序员眼中的关系,但在编译器眼中没有任何关系。正如文章解释的那样,导入java.awt.* 不会导入java.awt.font 中的任何类,它们是完全独立的包,在编程语言中没有任何层次关系。要导入java.awt.font 中的所有类,您必须导入java.awt.font.* 并且不会导入父包java.awt 或兄弟包(如java.awt.color)中的任何类。

        因此,尽管与程序员有明显的等级关系,但语言中确实没有任何等级关系。要访问给定包中的类,您必须从它们的确切包中导入它们。

        如果包实际上是层次结构,那么人们可能会想象会是这种情况。然而,层次结构仅用于组织代码并向程序员提示一组给定的包打算一起使用。

        【讨论】:

          【解决方案5】:

          把层次结构想象成一个文件系统。在 Java 中,包就像目录,类就像文件。包旨在包含一组相关的类。当存在逻辑相关的包组时,可以对其进行命名,以便它们显示为更大层次结构的成员。查看上面的 java.awt.* 示例,我可以将 AWT 的类放在 jar1 中。它将具有以下结构:

          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) 将包声明为其他人的包结构的扩展是非常糟糕的形式,即使编译器允许你这样做。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-01-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-02-13
            • 1970-01-01
            相关资源
            最近更新 更多