通常package包会把很多人搞糊涂于是我翻阅资料发现java编程思想中有比较详尽 的解释于是与大家分享希望能祝你一臂之力 package解析自己为机器上的一个目录这样一来Java程序运行并需要装载class文件的时候它就可以找到class文件驻留的那个目录 Java解释器的工作程序如下首先它找到环境变量CLASSPATH(将Java或者具有Java解释能力的工具——如浏览器——安装到机器中时通过操作系统进行设定)CLASSPATH包含了一个或多个目录它们作为一种特殊的根使用从这里展开对class文件的搜索从那个根开始解释器会寻找包名并将每个点号(句点)替换成一个斜槓从而生成从CLASSPATH根开始的一个路径名(所以package foobarbaz会变成foo\bar\baz或者foo/bar/baz具体是正斜槓还是反斜槓由操作系统决定)随后将它们连接到一起成为CLASSPATH内的各个条目(入口)以后搜索class文件时就可从这些地方开始查找与准备创建的类名对应的名字此外它也会搜索一些标准目录——这些目录与Java解释器驻留的地方有关 为进一步理解这个问题下面以我自己的域名为例它是将其反转过来后combruceeckel就为我的类创建了独一无二的全局名称(comeduorgnet等扩展名以前在Java包中都是大写的但自Java 以来这种情况已发生了变化现在整个包名都是小写的)由于决定创建一个名为util的库我可以进一步地分割它所以最后得到的包名如下 package combruceeckelutil; 现在可将这个包名作为下述两个文件的命名空间使用 //: Vectorjava // Creating a package package combruceeckelutil; public class Vector { public Vector() { Systemoutprintln( combruceeckelutilVector); } } ///:~ 创建自己的包时要求package语句必须是文件中的第一个非注释代码第二个文件表面看起来是类似的 //: Listjava // Creating a package package combruceeckelutil; public class List { public List() { Systemoutprintln( combruceeckelutilList); } } ///:~ 这两个文件都置于我自己系统的一个子目录中 C:\DOC\JavaT\com\bruceeckel\util 若通过它往回走就会发现包名combruceeckelutil但路径的第一部分又是什么呢?这是由CLASSPATH环境变量决定的在我的机器上它是 CLASSPATH=;D:\JAVA\LIB;C:\DOC\JavaT 可以看出CLASSPATH里能包含大量备用的搜索路径然而使用JAR文件时要注意一个问题必须将JAR文件的名字置于类路径里而不仅仅是它所在的路径所以对一个名为grapejar的JAR文件来说我们的类路径需要包括 CLASSPATH=;D:\JAVA\LIB;C:\flavors\grapejar 正确设置好类路径后可将下面这个文件置于任何目录里(若在执行该程序时遇到麻烦请参见第章的小节赋值) //: LibTestjava // Uses the library package c; import combruceeckelutil*; public class LibTest { public static void main(String[] args) { Vector v = new Vector(); List l = new List(); } } ///:~ 编译器遇到import语句后它会搜索由CLASSPATH指定的目录查找子目录com\bruceeckel\util然后查找名称适当的已编译文件(对于Vector是Vectorclass对于List则是Listclass)注意Vector和List内无论类还是需要的方法都必须设为public 恋灳 自动编译 为导入的类首次创建一个对象时(或者访问一个类的static成员时)编译器会在适当的目录里寻找同名的class文件(所以如果创建类X的一个对象就应该是Xclass)若只发现Xclass它就是必须使用的那一个类然而如果它在相同的目录中还发现了一个Xjava编译器就会比较两个文件的日期标记如果Xjava比Xclass新就会自动编译Xjava生成一个最新的Xclass 对于一个特定的类或在与它同名的java文件中没有找到它就会对那个类采取上述的处理 沖突 若通过*导入了两个库而且它们包括相同的名字这时会出现什么情况呢?例如假定一个程序使用了下述导入语句 import combruceeckelutil*; import javautil*; 由于javautil*也包含了一个Vector类所以这会造成潜在的沖突然而只要沖突并不真的发生那么就不会产生任何问题——这当然是最理想的情况因为否则的话就需要进行大量编程工作防范那些可能可能永远也不会发生的沖突 如现在试着生成一个Vector就肯定会发生沖突如下所示 Vector v = new Vector(); 它引用的到底是哪个Vector类呢?编译器对这个问题没有答案读者也不可能知道所以编译器会报告一个错误强迫我们进行明确的说明例如假设我想使用标准的Java Vector那么必须象下面这样编程 javautilVector v = new javautilVector(); 由于它(与CLASSPATH一起)完整指定了那个Vector的位置所以不再需要import javautil*语句除非还想使用来自javautil的其他东西 |