在 Java Project中,将所有.java文件保存在同一个文件夹中是否意味着它们在同一个包中?
与将所有项目文件保存在一个文件夹中相比,为我们的项目制作包有什么区别?
这个线程并没有真正解决我的问题。
包和目录之间存在关系,但这是您必须维护的关系。如果您有一个在“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(如果你使用它)有点混淆了这个问题,因为它“想要”提供目录和包名称,并且有时(但不总是)使它们保持同步。
包为您的类提供逻辑命名空间..
并且这些包以目录级别的形式存储(它们被转换为嵌套目录),以便为您的类提供物理分组(命名空间)。
另外,请注意physical
命名空间必须与logical
命名空间一致。你不能让你的类package com.demo
在目录结构下: - \com\demo\temp\
,它必须在\com\demo\
,并且这个目录被添加到类路径中,以便你的类是运行代码时对 JVM可见..
假设您具有以下目录结构:-
一个
|
+-- Sample.java(包含B包下的Demo类) | +-- Outer.java(包含Demo类 - 无包) | +--B | | | +-- 演示.class | +--C | | | +-- Abc.class | +-- Demo.class
假设您的类Abc.class
和Demo.class
(在目录 A 下)未定义在任何包下,而您的类Demo.class
(在目录 B 下)定义在package B
. 所以,你需要在你的类路径中有两个目录: - \A
(对于两个类: - Demo.class
和B.Demo.class
)和\A\C
(对于 class Abc.class
)..
Demo.class
。因为它们在不同的packages
. 这就是将它们划分为namespaces
.. 的全部意义。这是有益的,因为您不会用完您的类的唯一名称..了解类加载器子系统将回答您的查询。
给定一个完全限定的类型名称,原始类加载器必须以某种方式尝试使用该类型的简单名称加上“.class”来定位文件。因此,JVM 搜索存储在名为 CLASSPATH 的环境变量中的用户定义目录路径。原始加载程序按照目录出现在 CLASSPATH 中的顺序查找每个目录,直到找到具有适当名称的文件:类型的简单名称加上“.class”。除非该类型是未命名包的一部分,否则原始加载程序期望文件位于 CLASSPATH 中目录之一的子目录中。子目录的路径名是根据该类型的包名构建的。例如,如果原始类加载器正在搜索类 java.lang.Object,它将寻找 Object。