鍍金池/ 教程/ Java/ Java 包
Java 接口
Java 方法
Java 數(shù)字
Java 條件判斷
Java 異常處理
Java 字符
Java 重寫(xiě)
Java 網(wǎng)絡(luò)編程
Java 數(shù)據(jù)結(jié)構(gòu)
Java 的對(duì)象和類
Java 多線程
Java 封裝
Java 數(shù)組
Java Applet 基礎(chǔ)
Java 庫(kù)類
Java 抽象
Java 繼承
Java 正則表達(dá)式
Java 描述符的類型
Java 發(fā)送郵件
Java 序列化
Java 泛型
Java 多態(tài)
Java 變量類型
Java 基本數(shù)據(jù)類型
Java 包
Java 快速參考指南
Java 基本運(yùn)算符
Java 概述
Java 字符串
Java 循環(huán)控制
Java 環(huán)境設(shè)置
Java 文件注釋
Java 文件和 I/O
Java 集合
Java 基本語(yǔ)法
Java 日期和時(shí)間

Java 包

在 Java 中使用包是為了防止命名沖突,來(lái)控制訪問(wèn),使得搜索/定位和類、接口、枚舉和注釋等的使用更為簡(jiǎn)單。

包可以被定義為一組相關(guān)的類型(類、接口、枚舉和注釋),提供訪問(wèn)保護(hù)和命名空間管理。

在 Java 中一些已經(jīng)存在的包有:

  • java.lang - 包含了基本類
  • java.io - 包含有輸入,輸出功能的類

程序員可以定義自己的包來(lái)包含各種類和接口等。把你實(shí)現(xiàn)的相關(guān)類組織在一起是一種很好的做法,這樣一個(gè)程序員可以很簡(jiǎn)單的知道哪些類、接口、枚舉,注釋是相關(guān)的。

由于包創(chuàng)建了一個(gè)新的命名空間,因此將不會(huì)和其他包中的名字有任何名字沖突。使用包,可以很簡(jiǎn)單的提供訪問(wèn)控制,并且也可以很簡(jiǎn)單的定位到相關(guān)類。

創(chuàng)建包

當(dāng)創(chuàng)建一個(gè)包的時(shí)候,應(yīng)該為包起一個(gè)名字,并且把 package 名字的聲明語(yǔ)句放在每個(gè)包含類、接口、枚舉和注釋類型的源文件頂部。

package 聲明語(yǔ)句應(yīng)該放在源文件的第一行。在每個(gè)源文件中只能有一個(gè)包聲明語(yǔ)句,并且它適用于所有類型的文件。

如果沒(méi)有使用包聲明,那么類、接口、枚舉和注釋類型的將會(huì)被放進(jìn)一個(gè)無(wú)名的包中。

示例

讓我們來(lái)看創(chuàng)建了一個(gè)叫做 Animal 的包的例子。習(xí)慣上使用小寫(xiě)名字的包以避免和類、接口名字的沖突。

在包 animals 中聲明一個(gè)接口:

/* File name : Animal.java */
package animals;

interface Animal {
   public void eat();
   public void travel();
}

現(xiàn)在,在同一個(gè)包 animals 中實(shí)現(xiàn)一個(gè)類:

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();
   }
} 

現(xiàn)在,你可以編譯這兩個(gè)文件并將它們放置在一個(gè)叫做 animals 的子文件夾中,然后像下述來(lái)運(yùn)行:

$ mkdir animals
$ cp Animal.class  MammalInt.class animals
$ java animals/MammalInt
Mammal eats
Mammal travels

import 關(guān)鍵字

如果一個(gè)類想使用同一個(gè)包中的另一個(gè)類,就沒(méi)必要使用包名。同一個(gè)包中的類不用任何特殊的語(yǔ)法就可以彼此識(shí)別。

示例

一個(gè)叫做 Boss 的類添加進(jìn)了已經(jīng)包含了 Employee 的 payroll 包中。 在沒(méi)有使用 payroll 前綴的情況下,Boss 類引用了 Employee 類,像下面演示的 Boss 類:

package payroll;

public class Boss
{
   public void payEmployee(Employee e)
   {
      e.mailCheck();
   }
}

如果 Boss 類 沒(méi)有在 payroll 包中會(huì)發(fā)生什么?那么 Boss 類就必須使用下述的其中一種方法來(lái)引用位于其它包中的類。

  • 可以使用全名。例如:
payroll.Employee
  • 可以使用 import 關(guān)鍵字和通配符(*)來(lái)導(dǎo)入。例如:
import payroll.*;
  • 可以使用 import 關(guān)鍵字來(lái)導(dǎo)入類本身。例如:
import payroll.Employee;

注: 一個(gè)類的文件可以包含任意數(shù)量的導(dǎo)入語(yǔ)句。這些導(dǎo)入語(yǔ)句必須位于包聲明語(yǔ)句之后和類的定義語(yǔ)句之前。

包的目錄結(jié)構(gòu)

當(dāng)一個(gè)類放置在一個(gè)包中時(shí)主要會(huì)發(fā)生以下兩個(gè)結(jié)果:

  • 包的名字變成了類名字的一部分,就像我們?cè)谇耙粋€(gè)章節(jié)剛剛討論過(guò)的。
  • 包的名字必須和相關(guān)字節(jié)碼文件的目錄結(jié)構(gòu)匹配。

在 Java 里有以下一種管理文件的簡(jiǎn)單方式:

將類、接口、枚舉、注釋類型的源代碼存在一個(gè)擴(kuò)展名為 .java 的文本文件中。例如:

// File Name :  Car.java

package vehicle;

public class Car {
   // Class implementation.   
}

現(xiàn)在,將源文件放在一個(gè)其名字能夠反映出包的名字的文件夾中:

....\vehicle\Car.java

現(xiàn)在,正確的類名和路徑名應(yīng)該像下面這樣:

  • 類名 -> vehicle.Car
  • 路徑名 -> vehicle\Car.java (in windows)

一般情況下,一個(gè)公司使用它的逆序的互聯(lián)網(wǎng)域名當(dāng)做包的名稱。例如:某公司的互聯(lián)網(wǎng)域名是 apple.com ,那么它的包名應(yīng)該是以 com.apple 開(kāi)頭。包名的每一個(gè)部分反映了一個(gè)子目錄。

例如:一個(gè)公司有一個(gè)包含了 Dell.java 源文件的 com.apple.computers 的包,它將被包含在像下面的一系列子文件夾中:

....\com\apple\computers\Dell.java

在編譯的時(shí)候,編譯器為其中定義的每個(gè)類、接口和枚舉創(chuàng)建了一個(gè)不同的輸出文件。輸出文件的基本名字是類型名和 .class 的擴(kuò)展名。

例如:

// File Name: Dell.java

package com.apple.computers;
public class Dell{

}
class Ups{

}

現(xiàn)在,像下面使用 -d 選項(xiàng)來(lái)編譯這個(gè)文件:

$javac -d . Dell.java

這將像下面存放編譯后的文件:

.\com\apple\computers\Dell.class
.\com\apple\computers\Ups.class

你可以像下面這樣導(dǎo)入所有定義在 \com\apple\computers\ 中的類和接口:

import com.apple.computers.*;

像 .java 這樣的源文件, .class 這些編譯后的文件應(yīng)該在能夠反映出包名的一系列文件夾中。然而, .class 文件的路徑不用和 .java 源文件的路徑相同。你可以獨(dú)立的管理源文件和編譯后文件的目錄,如下:

<path-one>\sources\com\apple\computers\Dell.java

<path-two>\classes\com\apple\computers\Dell.class

通過(guò)這樣,可以把編譯過(guò)后的文件夾給其它的程序員而不用暴露你的源文件。同時(shí)你也需要使用這種方式來(lái)管理源文件和編譯過(guò)后的 class 文件以便編譯器和 Java 虛擬機(jī)(JVM)能夠找到程序中使用的所有類型。

編譯后文件夾的全路徑, \\classes, 叫做 class path, 在系統(tǒng)環(huán)境變量 CLASSPATH 中設(shè)置。編譯器和 JVM 通過(guò)添加包名到 class path 中來(lái)構(gòu)造 .class 文件的路徑。

我們說(shuō) \\classes 是 class path, 包名是 com.apple.computers ,然后編譯器和 JVM 將在 \\classes\com\apple\compters 中尋找 .class 文件。

一個(gè) class path 可能包含幾個(gè)路徑。多個(gè)路徑以分號(hào)(Windows)或者冒號(hào)(Unix)隔開(kāi)。默認(rèn)情況下,編譯器和 JVM 查找當(dāng)前目錄和包含 Java 平臺(tái)字節(jié)碼的 JAR 文件以便于這些文件夾自動(dòng)在 class path 中。

設(shè)置系統(tǒng)中的 CLASSPATH 環(huán)境變量

為了顯示當(dāng)前的 CLASSPATH 環(huán)境變量,使用以下在 Windows 和 UNIX(Bourne shell)中的命令:

  • 在 Windows 中 -> C:> set CLASSPATH
  • 在 UNIX 中 -> % echo $CLASSPATH

使用下述命令刪除當(dāng)前 CLASSPATH 變量中的內(nèi)容:

  • 在 Windows 中 -> C:> set CLASSPATH=
  • 在 UNIX 中 -> % unset CLASSPATH; export CLASSPATH

使用下述命令設(shè)置 CLASSPATH 變量:

  • 在 Windows 中 -> set CLASSPATH=C:\users\jack\java\classes
  • 在 UNIX 中 -> % CLASSPATH=/home/jack/java/classes; export CLASSPATH
上一篇:Java 集合下一篇:Java 數(shù)字