標籤:
為了更好地組織類,Java提供了包機制,用於區別類名的命名空間。
包的作用
- 1 把功能相似或相關的類或介面組織在同一個包中,方便類的尋找和使用。
- 2 如同檔案夾一樣,包也採用了樹形目錄的儲存方式。同一個包中的類名字是不同的,不同的包中的類的名字是可以相同的,當同時調用兩個不同包中相同類名的類時,應該加上包名加以區別。因此,包可以避免名字衝突。
- 3 包也限定了存取權限,擁有包存取權限的類才能訪問某個包中的類。
Java使用包(package)這種機制是為了防止命名衝突,存取控制,提供搜尋和定位類(class)、介面、枚舉(enumerations)和注釋(annotation)等。
包語句的文法格式為:
package pkg1[.pkg2[.pkg3…]];
例如,一個Something.java 檔案它的內容
package net.java.utilpublic class Something{ ...}
那麼它的路徑應該是 net/java/Something.java 這樣儲存的。 package(包)的作用是把不同的java程式分類儲存,更方便的被其他java程式調用。
一個包(package)可以定義為一組相互聯絡的類型(類、介面、枚舉和注釋),為這些類型提供訪問保護和命名空間管理的功能。
以下是一些Java中的包:
- java.lang-打包基礎的類
- java.io-包含輸入輸出功能的函數
開發人員可以自己把一組類和介面等打包,並定義自己的package。而且在實際開發中這樣做是值得提倡的,當你自己完成類的實現之後,將相關的類分組,可以讓其他的編程者更容易地確定哪些類、介面、枚舉和注釋等是相關的。
由於package建立了新的命名空間(namespace),所以不會跟其他package中的任何名字產生命名衝突。使用包這種機制,更容易實現存取控制,並且讓定位相關類更加簡單。建立包
建立package的時候,你需要為這個package取一個合適的名字。之後,如果其他的一個源檔案包含了這個包提供的類、介面、枚舉或者注釋類型的時候,都必須將這個package的聲明放在這個源檔案的開頭。
包聲明應該在源檔案的第一行,每個源檔案只能有一個包聲明,這個檔案中的每個類型都應用於它。
如果一個源檔案中沒有使用包聲明,那麼其中的類,函數,枚舉,注釋等將被放在一個無名的包(unnamed package)中。例子
讓我們來看一個例子,這個例子建立了一個叫做animals的包。通常使用小寫字母來命名避免與類、介面名字的衝突。
在animals包中加入一個介面(interface):
/* 檔案名稱: Animal.java */package animals;interface Animal { public void eat(); public void travel();}
接下來,在同一個包中加入該介面的實現:
package animals;/* 檔案名稱 : MammalInt.java */public class MammalInt implements Animal{ public void eat(){ System.out.println("Mammal eats"); } public void travel(){ System.out.println("Mammal travels"); } public int noOfLegs(){ return 0; } public static void main(String args[]){ MammalInt m = new MammalInt(); m.eat(); m.travel(); }}
然後,編譯這兩個檔案,並把他們放在一個叫做animals的子目錄中。 用下面的命令來運行:
$ mkdir animals$ cp Animal.class MammalInt.class animals$ java animals/MammalIntMammal eatsMammal travel
package的目錄結構
類放在包中會有兩種主要的結果:
- 包名成為類名的一部分,正如我們前面討論的一樣。
- 包名必須與相應的位元組碼所在的目錄結構相吻合。
下面是管理你自己java中檔案的一種簡單方式:
將類、介面等類型的源碼放在一個文本中,這個檔案的名字就是這個類型的名字,並以.java作為副檔名。例如:
// 檔案名稱 : Car.javapackage vehicle;public class Car { // 類實現 }
接下來,把源檔案放在一個目錄中,這個目錄要對應類所在包的名字。
....\vehicle\Car.java
現在,正確的類名和路徑將會是如下樣子:
通常,一個公司使用它互連網網域名稱的顛倒形式來作為它的包名.例如:互連網網域名稱是apple.com,所有的包名都以com.apple開頭。包名中的每一個部分對應一個子目錄。
例如:這個公司有一個com.apple.computers的包,這個包包含一個叫做Dell.java的源檔案,那麼相應的,應該有如下面的一連串子目錄:
....\com\apple\computers\Dell.java
編譯的時候,編譯器為包中定義的每個類、介面等類型各建立一個不同的輸出檔案,輸出檔案的名字就是這個類型的名字,並加上.class作為擴充尾碼。 例如:
// 檔案名稱: Dell.javapackage com.apple.computers;public class Dell{ }class Ups{ }
現在,我們用-d選項來編譯這個檔案,如下:
$javac -d . Dell.java
這樣會像下面這樣放置編譯了的檔案:
.\com\apple\computers\Dell.class.\com\apple\computers\Ups.class
你可以像下面這樣來匯入所有 \com\apple\computers\中定義的類、介面等:
import com.apple.computers.*;
編譯之後的.class檔案應該和.java源檔案一樣,它們放置的目錄應該跟包的名字對應起來。但是,並不要求.class檔案的路徑跟相應的.java的路徑一樣。你可以分開來安排源碼和類的目錄。
<path-one>\sources\com\apple\computers\Dell.java<path-two>\classes\com\apple\computers\Dell.class
這樣,你可以將你的類目錄分享給其他的編程人員,而不用透露自己的源碼。用這種方法管理源碼和類檔案可以讓編譯器和java虛擬機器(JVM)可以找到你程式中使用的所有類型。
類目錄的絕對路徑叫做class path。設定在系統變數CLASSPATH中。編譯器和java虛擬機器通過將package名字加到class path後來構造.class檔案的路徑。
<path- two>\classes是class path,package名字是com.apple.computers,而編譯器和JVM會在 <path-two>\classes\com\apple\compters中找.class檔案。
一個class path可能會包含好幾個路徑。多重路徑應該用分隔字元分開。預設情況下,編譯器和JVM尋找目前的目錄。JAR檔案按包含Java平台相關的類,所以他們的目錄預設放在了class path中。
Java 包(package)詳解