在尝试建立自己的可重用package的时候,对package和import语句做了些试验,记录结果如下。
使用说明:
(1)对于src\com\cjren\util\ClassA.java这个提供给其他类使用的class.
package com.cjren.util;
public class ClassA {
...
}
编译时:
javac -d . ClassA.java // -d . 表示了以当前目录为package语句生成的相对根目录。
结果是在ClassA.java所在的目录下生成了com.cjren.util包,里面含ClassA.class,这个包可以复制剪贴到其他的地方供其他类使用。
Notes:
必须使用"-d .",否则ClassA.class并不会放在com.cjren.util包里面,而是生成在和ClassA.java相同的目录下。
(2)对于要使用ClassA的ClassB.java.
import com.cjren.util.ClassA;
public class ClassB {
... // use ClassA here
}
To compile: javac ClassB.java
To run: 假设com包放在和ClassB.java的当前目录
java ClassB
// or java -cp . ClassB // here use the "-cp ." as the current directory to find the package com.
假设com包放在D:\Program Files\Java\mypackages下
java -cp D:\Program Files\Java\mypackages ClassB
Notes:
错误一:
package com.cjren.util;
public class ClassA {
...
}
编译后直接把com.cjren.util包里面的ClassA.class文件拷贝到和ClassB.java相同的目录下直接使用,
public class ClassB {
... // use ClassA here
}
To compile: javac ClassB.java
错误信息是
"ClassB.java:某一行: 无法访问 ClassA
错误的类文件: .\ClassA.class
类文件包含错误的类: com.cjren.util.ClassA
请删除该文件或确保该文件位于正确的类路径子目录中。"
想一想为什么出错信息是说:“错误的类文件: .\ClassA.class, 类文件包含错误的类: com.cjren.util.ClassA”呢?因为"错误的类文件: .\ClassA.class"当中包含了"错误的类: com.cjren.util.ClassA"这个信息,而这个"com.cjren.util.ClassA"是在ClassA.java中的"package com.cjren.util;"语句所造成的。
正确的做法是把ClassA.class所在的包整个复制粘贴到ClassB.java所在的目录下,或者在ClassB.java所在的目录下人为手动的建立com\cjren\util\目录,然后直接把ClassA.class文件复制粘贴到此。这暗示了代码生成的包和手动建立的目录可能是一样。
可见,当ClassA.java的源代码中含"package com.cjren.util;"语句,则生成com.cjren.util包里面的ClassA.class文件里面应该就也包含了自己这个class文件所属的包信息,所以这个ClassA.class只能放在这个代码中已经指定的特定包的路径下使用,而不能把这个ClassA.class独立出来使用,因为这样的话将ClassA.class文件属性中的的包信息不相符。当然当这个ClassA.java没有显式地制定package语句信息时候,我怀疑(也觉得应该)是默认在ClassA.class文件当中包含了包的信息就是".",可以理解为默认的加入了"package .;"语句。
错误二:
public class ClassA {
...
}
编译后这个ClassA.class文件中含有的包的信息是"."当前目录就包!
把这个ClassA.class文件,移到以ClassB.java所在的目录为当前父目录的人为手动建立的com\cjren\util目录下。
import com.cjren.util.ClassA;
public class ClassB {
... // use ClassA here
}
To compile: javac ClassB.java
错误信息是
"ClassB.java:某一行: 无法访问 com.cjren.swing.ClassA
错误的类文件: .\com\cjren\util\ClassA.class
类文件包含错误的类: ClassA
请删除该文件或确保该文件位于正确的类路径子目录中。"
想一想为什么出错信息是说:“错误的类文件: .\com\cjren\util\ClassA.class,类文件包含错误的类: ClassA”呢?因为你这个com.cjren.util包中的ClassA.class文件本来所默认的包信息是".",在ClassA.java中并没有使用"package"语句指定ClassA应该属于包com\cjren\util这个信息。
小结:
在尝试过程当中发现,
public class ClassA {
...
}
和
package com.cjren.util;
public class ClassA {
...
}
这两个只差了一个package语句的class文件大小有十几到几十k上的区别,这可能进一步证明了.java文件中的package语句会在.class文件中加入相应的包信息,这个包信息决定了这个class被使用时候的方式(是否需要import特定的包)。
还有一点要注意的是:
package com.cjren.util;
public class ClassA {
...
}
之后无论是使用 javac ClassA.java 或者 javac -d . ClassA.java编译都不会影响ClassA.class文件当中所含有的包信息,这两种编译方式所造成的区别在上面的使用说明中已经说过了。