使用套件管理,解決了實體檔案與撰寫程式時類別名稱衝突的問題,但若每次撰寫程式時,都得鍵入完全吻合名稱,卻也是件麻煩的事,想想看,有些套件定義的名稱很長時,單是要鍵入完全吻合名稱得花多少時間。
你可以用import
偷懶一下,例如:
package cc.openhome;
import cc.openhome.util.Console;
public class Main {
public static void main(String[] args) {
Console.writeLine("Hello World");
}
}
編譯與執行時的指令方式,與 使用 package 管理類別 中談過的相同。當編譯器剖析Main.java看到import
宣告時,會先記得import
的名稱,後續剖析程式時,若看到Console
名稱,原本會不知道Console
是什麼東西,但編譯器記得你用import
告訴過它,如果遇到不認識的名稱,可以比對一下import
過的名稱,編譯器試著使用cc.openhome.util.Console
,結果可以在指定的類別路徑中,cc/openhome/util資料夾下找到Console.class,於是可以進行編譯。
所以import
只是告訴編譯器,遇到不認識的類別名稱,可以嘗試使用import
過的名稱,import
讓你少打一些字,讓編譯器多為你作一些事。
如果同一套件下會使用到多個類別,你也許會多次使用import
:
import cc.openhome.Message;
import cc.openhome.User;
import cc.openhome.Address;
你可以更偷懶一些,用以下的import
語句:
import cc.openhome.*;
先前程式也可以使用以下的import
語句,而編譯與執行結果相同:
import cc.openhome.util.*;
當編譯器剖析Main.java看到import
的宣告時,會先記得有cc.openhome.util
套件名稱,在後續剖析到Console
名稱時,發現它不認識Cosnole
是什麼東西,但編譯器記得你用import
告訴過它,若遇到不認識的名稱,可以比對一下import
過的名稱,編譯器試著將cc.openhome.util
與Console
結合為cc.openhome.util.Console
,結果可以在指定的類別路徑中,cc/openhome/util資料夾下找到Console.class,於是可以進行編譯。
偷懶也是有個限度,如果你自己寫了一個Arrays
:
package cc.openhome;
public class Arrays {
...
}
若在某個類別中撰寫有以下的程式碼:
import cc.openhome.*;
import java.util.*;
public class Some {
public static void main(String[] args) {
Arrays arrays;
...
}
}
那麼編譯時,你會發現有以下錯誤訊息:
src\Some.java:6: error: reference to Arrays is ambiguous
Arrays arrays;
^
both class java.util.Arrays in java.util and class cc.openhome.Arrays in cc.op
enhome match
1 error
當編譯器剖析Some.java看到
import
的宣告時,會先記得有cc.openhome
套件名稱,在繼續剖析至Arrays
該行時,發現它不認識Arrays
是什麼東西,但編譯器記得你用import
告訴過他,若遇到不認識的名稱,可以比對import
過的名稱,編譯器試著將cc.openhome
與Arrays
結合在一起為cc.openhome.Arrays
,結果可以在類別路徑中,cc/openhome資料夾下找到Arrays.class。然而,編譯器試著將
java.util
與Arrays
結合在一起為java.util.Arrays
,發現也可以在Java SE API的rt.jar中(預設的類別載入路徑之一),對應的java/util資料夾中找到Arrays.class,於是編譯器困惑了,到底該使用cc.openhome.Arrays
還是java.util.Arrays
?遇到這種情況時,就不能偷懶了,你要使用哪個類別名稱,就得明確地逐字打出來:
import cc.openhome.*;
import java.util.*;
public class Some {
public static void main(String[] args) {
cc.openhome.Arrays arrays;
...
}
}
這個程式就可以通過編譯了。簡單地說,
import
是偷懶工具,不能偷懶就回歸最保守的寫法。在Java SE API中有許多常用類別,像是寫第一個Java程式時使用的
System
類別,其實也有使用套件管理,完整名稱其實是java.lang.System
,在java.lang
套件下的類別由於很常用,不用撰寫import
也可以直接使用class
定義的名稱,這也就是為何不用如下撰寫程式的原因(寫了當然也沒關係,只是自找麻煩):java.lang.System.out.println("Hello!World!");
如果類別位於同一套件,彼此使用並不需要
import
,當編譯器看到一個沒有套件管理的類別名稱,會先在同一套件中尋找類別,如果找到就使用,若沒找到,再試著從import
陳述進行比對。java.lang
可視為預設就有import
,沒有寫任何import
陳述時,也會試著比對java.lang
的組合,看看是否能找到對應類別。原始碼檔案或位元碼檔案,都可以使用JAR檔案封裝,在文字模式下,可以使用JDK的jar工具程式來製作JAR檔案,你可以參考 JAR 檔中的原始檔、類別檔。