Java中包和目录的区别

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

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

这个post并没有真正解决我的问题。

包和目录之间存在关系,但它是必须维护的关系。 如果你有一个在“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”这样的软件包很有礼貌(取代你的名字和当然是项目),所以你给它的人可以将它与其他人合并而不会出现名称冲突。

在大型应用程序中,您会发现使用更高级别的分离可以帮助您保持function正常,因此您可以知道所有内容。 它也阻止你在不同的function区域之间“越过边界”,所以你不会让不相关的逻辑陷入困境。

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

  • 为您的类提供逻辑命名空间。

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

另请注意, physical命名空间必须与logical命名空间一致。在目录结构下,您不能拥有package com.demo的类: – \com\demo\temp\它必须位于\com\demo\ ,并且此目录被添加到类路径中,以便在运行代码时JVM 可以看到您的类。

假设您有以下目录结构: –

一个
|
+ – Sample.java(包含包B下的Demo类)
|
+ – Outer.java(包含演示类 – 没有包)
|
+ – B
| |
| + – Demo.class
|
+ – Ç
| |
| + – Abc.class
|
+ – Demo.class

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

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

理解类加载器子系统将回答您的查询。

参考Bill Venners的Inside JVM

给定一个完全限定的类型名称,原始类加载器必须以某种方式尝试查找类型为简单名称加“.class”的文件。 因此,JVM搜索存储在名为CLASSPATH的环境变量中的用户定义的目录路径。 原始加载器按照目录在CLASSPATH中出现的顺序查找每个目录,直到找到具有相应名称的文件:类型的简单名称加上“.class”。 除非类型是未命名包的一部分,否则原始加载程序希望该文件位于CLASSPATH目录中的一个子目录中。 子目录的路径名是根据类型的包名称构建的。 例如,如果原始类加载器正在搜索类java.lang.Object,它将在每个CLASSPATH目录的java \ lang子目录中查找Object.class。