【问题标题】:Difference between Package and Directory in JavaJava中包和目录的区别
【发布时间】:2012-09-21 02:23:13
【问题描述】:

Java 项目中,是否将所有.java 文件保存在同一个文件夹中是否意味着它们在同一个包中?

为我们的项目制作一个包与将所有项目文件保存在一个文件夹中相比有什么区别?

This thread 并没有真正解决我的问题。

【问题讨论】:

  • 谷歌搜索你的标题会得到这个链接stackoverflow.com/questions/9510932/…
  • 我不明白。请澄清。!
  • 这意味着,这个问题已经被问过了,你应该先查找这个问题和类似的问题。
  • 我知道,但我无法理解已经提出的问题的答案。
  • 是的,我认为其他问题的答案有点糟糕。

标签: java directory packages


【解决方案1】:

包和目录之间存在关系,但它是必须维护的。如果您有一个在“mypackage1.mypackage2”中的类,这意味着java 命令将期望在名为“mypackage1\mypackage2”的目录结构中找到它(假设“向后”Windows 表示法),该目录结构进一步嵌入到一个目录中(我们称之为“myjava”),其名称在classpath 中(或者直接在“当前目录”中)。

因此,您的 Java 类(内部称为 package mypackage1.mypackage2;)位于“\Users\myName\myjava\mypackage1\mypackage2\”中,并且您将“\Users\myName\myjava”放在类路径中,否则您将当前目录设置为“\Users\myName\myjava”。

如果你把它弄混了,要么根本找不到这个类,要么你会得到一个类似模糊不清的“NoClassDefFoundError”的错误。

至于为什么会使用包(和目录),原因与“名称空间”和“关注点分离”(查找这些)有关。如果没有包并且所有“java.lang”、“java.io”、“sun.misc”等类都在一起,Java 将更难保持直截了当。首先,必须使用名称“前缀”来保持它们的正确性并避免名称冲突。而且大部分逻辑分组都会丢失。

对于您自己的项目,您不需要为自己编写的简单小程序使用包,但是如果您编写一些可能会提供给其他人的东西,那么使用诸如“myname.myproject”之类的包是有礼貌的(替换为当然是你的名字和项目),所以你给它的人可以将它与其他人组合起来而不会发生名称冲突。

在大型应用程序中,您会发现使用更深层次的分离可以帮助您保持功能正常,因此您可以知道所有内容的位置。它还阻止您在不同功能区域之间“跨越边界”,因此您不会将不相关的逻辑交织在一起。

Eclipse(如果你使用它的话)有点混淆了这个问题,因为它“想要”提供目录和包名,并且有时(但不总是)会让它们保持同步。

【讨论】:

  • 所以可以说我在文件夹 \java\limbo\ 中有一个 .java 文件,它需要使用同样位于同一个 \java\limbo 中的其他文件中的类(another.java 文件) \ 放置,在两个文件的开头,我写了 packagelimbo; 但是当我编译时,我得到第一个文件的 ClassNotFound 错误,它需要在同一文件夹中的第二个类,那是怎么回事?
  • @jtnks -- 编译时必须设置有效的类路径,就像运行 java 命令时一样。对于您的方案,cd \java 然后运行 ​​javac limbo\MyClass.java。这会将两个类放在它们的包名称和目录结构方面的适当位置。
  • 非常感谢@HotLicks..它工作得很好,现在它的包装也很好。!!
  • 我不确定,但同一个包中的类可能存在于不同的目录中。看看这篇文章:docs.oracle.com/javase/8/docs/technotes/tools/windows/…。部分:类路径和包名称:...An interesting consequence of the package specification mechanism is that files that are part of the same package can exist in different directories. The package name is the same for each class, but the path to each file might start from a different directory in the class path....
  • @Xenomorph - 可能从类路径中的不同目录开始。您可能在类路径中的 dir1、dir2 和 dir3 中有包 a.b 的类,但每个目录中都必须有一个 a\b 目录。
【解决方案2】:
  • 为您的类提供逻辑命名空间..

  • 这些包以目录级别的形式存储(它们被转换为嵌套的目录),以便为您的类提供物理分组(命名空间)。 .

另外,请注意physical 命名空间必须与logical 命名空间一致。您不能在目录结构下拥有package com.demo 的类:-@ 987654324@,它必须\com\demo\下,并且这个目录被添加到classpath,这样你的类在当时对JVM可见它运行你的代码..

假设你有以下目录结构:-

A
|
+-- Sample.java(包含包B下的Demo类)
|
+-- Outer .java(包含 Demo 类 - 无包)
|
+--B
| |
| +-- Demo.class
|
+--C
| |
| +-- Abc.class
|
+-- Demo.class

假设,您的类 Abc.classDemo.class(在目录 A 下)未定义在任何包下,您的类 Demo.class(在目录 B 下)定义在 @ 987654329@。因此,您需要在类路径中有两个目录:-\A(对于两个类:-Demo.classB.Demo.class)和 \A\C(对于类 Abc.class)..

  • 不同包下的类可以使用相同的名称。这就是为什么上面定义的两个Demo.class 之间不会有任何冲突的原因。因为它们在不同的packages 中。这就是将它们划分为 namespaces.. 的全部意义。这是有益的,因为您的类不会用完唯一名称..

【讨论】:

    【解决方案3】:

    了解类加载器子系统将回答您的问题。

    参考Inside JVM by Bill Venners

    给定一个完全限定的类型名称,原始类加载器必须在 以某种方式尝试使用类型的简单名称加上 “。班级”。因此,JVM 搜索存储在 一个名为 CLASSPATH 的环境变量。原始装载机看起来 在每个目录中,按照目录出现在 CLASSPATH,直到找到具有适当名称的文件:类型的 简单的名称加上“.class”。除非类型是未命名的一部分 包,原始加载器期望文件位于 CLASSPATH 中目录之一的子目录。的路径名 子目录是根据类型的包名称构建的。为了 例如,如果原始类加载器正在搜索类 java.lang.Object,它将在 java\lang 中查找 Object.class 每个 CLASSPATH 目录的子目录。

    【讨论】:

      猜你喜欢
      • 2019-12-10
      • 2011-10-16
      • 2011-09-21
      • 1970-01-01
      • 2018-10-13
      • 2013-02-26
      • 2019-09-05
      • 1970-01-01
      • 2015-07-08
      相关资源
      最近更新 更多