【发布时间】:2013-10-07 00:09:19
【问题描述】:
我确定我误解了 Java 语言规范中的某些内容,但我不知道是什么。我的问题是:在许多系统上,java 强制目录结构并行包名,即如果包名是 foo.bar,那么包文件应该驻留在文件夹 foo/bar 中。但是,这不是 Java 语言规范的一部分,被认为是可选的。那么,如果您在一个执行这些规则的平台上实现 Java 而另一个不执行这些规则,该怎么办?需要文件层次结构的实现是否能够在其他实现使用的非结构化包中找到文件? Java 是否总是递归搜索所有类路径中的类文件?如果是这样,那为什么需要包名来模仿目录结构呢?
编辑: 例如,假设我们有两个 java 文件 one.java 和 two.java。在这些文件的顶部,我们预先添加“package foo.bar;”因此将这些文件标记为包 foo.bar。现在,大多数 Java 实现将使我们将这些文件放入文件层次结构中,以便我们拥有 /foo/bar/one.java 和 /foo/bar/two.java。但是,根据 JLS,这不是必需的。现在,假设我们有一个 Java 实现,它不会强制我们将它们放在一个层次结构中。也就是说,我们有一个 .jar 文件,它在顶层目录中有内容 one.java 和 two.java。现在,如果我们将该 .jar 文件加载到依赖文件层次结构来定位类文件的系统中,它是否能够找到这些类文件?
编辑: 因此,经过一些实验,我发现如果您通过 jar cvf foo.jar one.class two.class 设置没有适当目录层次结构的包,然后尝试将它们作为 foo.bar.two 和 foo 导入。 bar.one 即使指定了包,它也不起作用 - 你得到一个 NoClassDefFoundError。考虑到http://docs.oracle.com/javase/tutorial/java/package/managingfiles.html 说:“Java 平台的许多实现依赖于分层文件系统来管理源文件和类文件,这对我来说是一个非常有趣的结果,尽管 Java 语言规范不需要这样做。”
简而言之,这意味着如果您正在处理决定使用分层目录结构来管理包(几乎是所有包)的 Java 实现,那么生成的 jar 文件可能与其他系统不兼容它没有以相同的方式实现。 Java 社区似乎已经按照惯例解决了这个问题,但如果有任何其他信息,我很想听听更多。
【问题讨论】:
-
1- 包名称提供名称空间上下文,允许您拥有两个具有相同但位于不同包中的类。 2-Java 在查找类时将包名称转换为搜索。因此,如果您有一个名为
Wally的类,并且它被声明驻留在foo.bar中,Java 将通过为其已知的类路径元素添加前缀来查找foo/bar/Wally.class,否则它不会真正知道它在寻找什么或者确保它找到了正确的东西:P -
嗯,这就是令人困惑的地方:“Java 平台的许多实现依赖于分层文件系统来管理源文件和类文件,尽管 Java 语言规范并不要求这样做。”来自docs.oracle.com/javase/tutorial/java/package/managingfiles.html。这意味着不依赖文件系统层次结构的 java 实现有其他方法来识别 .class 文件的位置。但是使用该系统打包的 jar 文件与使用文件系统层次结构设置的 jar 文件不兼容,因为 java 不知道在哪里查找。
-
好的,但即便如此,Java 的大多数实现都依赖文件系统层次结构来定位 .class 文件,但这不是必需的。因此,如果您有一个不依赖文件系统的 Java 实现,那么依赖文件系统的外部 Java 实现将无法定位 .class 文件。
-
@doliver,下面 EJP 的回答是否回答了这个问题?如果是这样,请单击左侧的勾号接受它。这有助于系统区分未回答和已回答的问题。谢谢。
-
@halfer,不,这个问题没有答案。 EJP误解了我相信的问题。请随意查看我在上面 EJP 发布他的答案后所做的编辑。