Java包/package
在Java中使用包,以防止命名衝突,控製訪問,使搜索/定位和類,接口,枚舉和注解的使用更容易,等等。
一個包可以被定義為相關類型(類,接口,枚舉和注解)提供訪問保護和命名空間管理的分組。
一些在Java中現有的包是:
-
java.lang - 捆綁的基礎類
-
java.io - 用於輸入,輸出功能的類捆綁在這個包
程序員可以定義自己的包捆綁組的類/接口等,這是一個很好的做法來實現相關的類,使程序員可以很容易地確定的類,接口,枚舉,注釋都是相關的。
由於包創建一個新的命名空間不會有與其他包名稱的任何名稱衝突。使用包,它更容易提供訪問控製,它也更容易找到相關的類。
創建一個包:
創建一個包的時候,應該選擇的包的名稱,並把包語句具有該名稱在每個源文件的頂部,包含要在包中包括的類,接口,枚舉和注解類型。
package語句必須是源文件中的第一行。隻能有各一個源文件中package語句,並且它適用於所有類型的文件中。
如果不使用package語句則類,接口,枚舉和注釋類型將被放入一個未命名的包。
例子:
讓我們看看它創建了一個名為 animals 包的示例。它是用小寫名稱,以避免與類,接口名稱的任何衝突常見的做法。
把一個接口放在包animals:
/* File name : Animal.java */ package animals; interface Animal { public void eat(); public void travel(); }
現在,把一個實現在同一個 animals 包中:
package animals; /* File name : 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/MammalInt Mammal eats Mammal travels
import 關鍵字:
如果一個類希望使用另一個類在同一包中,包的名稱並不需要被使用。在同一個包中的類發現對方冇有任何特殊的語法。
例子:
在這裡,一個叫Boss類添加到已包含Employee的payroll 包。然後,Boss可以參考Employee類,而不使用前綴工資,主要表現如以下Boss類。
package payroll; public class Boss { public void payEmployee(Employee e) { e.mailCheck(); } }
如果Boss類不在payroll 包會發生什麼?Boss類必須然後使用下列方法之一來引用類在不同的包。
-
可以使用類的完全限定名。例如:
payroll.Employee
-
包可以使用import關鍵字和通配符(*)導入。例如:
import payroll.*;
-
類本身可以使用import關鍵字導入。例如:
import payroll.Employee;
注:一個類文件可以包含任意數量的導入語句。 package語句之後,並在類聲明之前的import語句必須出現。
軟件包的目錄結構:
當一個類被放置在一個包中發生兩個主要結果:
-
包的名稱將成為類的名稱的一部分,正如我們在上一節剛剛討論。
-
包的名稱必須與相應的字節碼所在的目錄結構相匹配。
下麵是簡單的管理中的Java文件的方式:
把源代碼的類,接口,枚舉或注釋類型在一個文本文件,其名稱的類型,其擴展名是 .java。例如:
// File Name : Car.java package vehicle; public class Car { // Class implementation. }
現在,把源文件中的目錄,其名稱反映了類所屬的包的名稱:
....vehicleCar.java
現在,合格的類名和路徑名會是如下:
-
類名稱 -> vehicle.Car
-
路徑名稱 -> vehicleCar.java (in windows)
一般情況下,一家公司使用其反向的Internet域名,其包名。例:某公司的Internet域名是apple.com,那麼它的所有包名就開始就可以為 com.apple。包名稱的每個組件對應一個子目錄。
例如:公司有包含一個Dell.java源文件com.apple.computers包,將它包含在一係列這樣的子目錄:
....comapplecomputersDell.java
在編譯時,編譯器會為它定義的每個類,接口和枚舉不同的輸出文件。輸出文件的基本名稱是類型的名稱,及其擴展名是 .class
例如:
// File Name: Dell.java package com.apple.computers; public class Dell{ } class Ups{ }
現在,編譯該文件使用-d選項,如下所示:
$javac -d . Dell.java
這將使編譯後的文件如下所示:
.comapplecomputersDell.class .comapplecomputersUps.class
可以導入所有已定義的類或接口 comapplecomputers 如下:
import com.apple.computers.*;
像 .java源文件,編譯後的 .class文件應該是在一個係列,反映包名的目錄。然而,類文件並不一定是相同的 .java源文件路徑。可以單獨安排源文件和類目錄,如:
<path-one>sourcescomapplecomputersDell.java <path-two>classescomapplecomputersDell.class
通過這樣做,可以給classes目錄到其他程序員不透露源代碼。還需要管理這種方式的源文件和類文件,使編譯器和Java虛擬機(JVM)可以找到所有程序使用的類型。
完整路徑的classes目錄,<path-two>類,被稱為類路徑,並設置與CLASSPATH係統變量。無論是編譯器和JVM通過將包名到類路徑構建的路徑 .class 文件。
<path-two>classes是類路徑和包名是com.apple.computers,那麼編譯器和JVM將尋找在<path-two>classescomapplecompters 文件中的 .class文件。
類路徑可能包括幾個路徑。多條路徑應該用分號(Windows)或冒號(UNIX)分隔。默認情況下,編譯器和JVM搜索當前目錄,並包含了Java平台的類,使這些目錄會自動在類路徑的JAR文件。
設置CLASSPATH係統變量:
要顯示當前的CLASSPATH變量,使用Windows和UNIX(Bourne shell的)下麵的命令:
-
在Windows -> C:> set CLASSPATH
-
在UNIX -> % echo $CLASSPATH
要刪除CLASSPATH變量的當前內容,使用:
-
在 Windows -> C:> set CLASSPATH=
-
在 UNIX -> % unset CLASSPATH; export CLASSPATH
要設置CLASSPATH變量:
-
在 Windows -> set CLASSPATH=C:usersjackjavaclasses
-
在 UNIX -> % CLASSPATH=/home/jack/java/classes; export CLASSPATH