在嘗試建立自己的可重用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文件當中所含有的包信息,這兩種編譯方式所造成的區別在上面的使用說明中已經說過了。
?