建立Java包,布局源文件和設置classpath參數之間相互影響。也相互關聯。正確建立和導入JAVA包,合理布局源文件,準確設置CLASSPATH參數,才能保證應用程序順利執行,并有效管理應用程序。
包的建立方法
Java包通過package語句建立,基本語法是:
package cn.edu.jmu.graphis;
在定義類或接口的源文件開始處,通過package語句,可以將相應的類或接口放入package所聲明的包里。包是相關類和接口的集合,提供了訪問級別控制和命名控件管理。
包的使用方法
每個源文件只能有一個包聲明,并且一定要求放在源文件的開始位置。如果一個源文件沒有包語句,則源文件所定義的類或接口唄系統放入默認包中。包有層次,層次間由點分隔。
例如有一組與圖形相關的類,包括Circles,Rectangles,Lines和points類等,描述了畫圖所用到的各種圖形組件,另有抽象類Graphic標識圖形組件的共性,接口Draggable表示用戶可以通過鼠標拖拽成圖的圖形組件。在這種情況下,我們不僅需要,而且也應該將這些相關類和接口組成包,可命名為graphics如:
//Graphics.java
package graphics;
public abstract class Graphic{
...
}
//Circle.java
package graphics;
public class Circle extends Graphic implements Draggable {
...
}
//Rectangle.java
package graphics;
public class Rectangle extends Graphic implements Draggable {
...
}
//Draggable.java
package graphics;
public interface Draggable{
...
}
通過創建和使用包,程序員不僅可以很容易地確定哪些類和接口是相關的,也可以很容易地找到提供特定功能的類和接口,例如,與畫圖有關的類和接口在graphics包中。
包的訪問權限
通過聲明類的訪問級別,可以控制對類的訪問權限。
類的訪問級別分為默認級和public級。定義類的默認訪問級別不需要任何關鍵字,唄聲明為默認級的類只對同一個包中的類是可視的。也就是說只有同一個包內的類實例可以訪問這個類,外界不能訪問它。如果用關鍵字public定義類,不但同一個包里的其他類可以訪問這個類,其他包中的類也可以訪問它。換句話說,同一個包中的類,相互之間有不受限制的訪問權限。而在不同包中,只有public類可以被訪問。
public修飾符不知用于定義類的訪問控制級別,也可以應用于接口,方法或變量。public 接口同public類一樣,可以由應用程序中的任何類訪問。而public方法或public屬性對任何可以訪問他的類或接口都是可視的。
除public修飾符之外,用于訪問控制的修飾符還有protected 和 private。
protected 或 private 僅用來定義方法或變量的訪問控制級別。protected 方法或protected變量僅對同一個包內的類或不同包中的子類來說是可視的。
private方法和pvivate變量對外部定義的類均不可視。
包的命名方式
包提供了心的命名控件,即使所定義的類使用與其他包中的類相同的名字,只要包類所屬的包不同名,就不會引起沖突。原因是這些類的全程限定名稱不同。類的全程限定包含了類的各層包名。這實質上是應用了面向對象的概念,將類封裝入包中。
包的訪問權限
通過聲明類的訪問級別,可以控制對類的訪問權限。
類的訪問級別分為默認級和public級。定義類的默認訪問級別不需要任何關鍵字,貝聲明為默認級的類只對同一個包中的類是可視的。也就是說,只有同一個包內的類實例可以訪問這個類,外界不能訪問它。如果用關鍵字public 定義類,不但同一個包里的其他類可以訪問這個類,其他包中的類也可以訪問它。換句話說,同一個包中的類,相互之間有不受限制的訪問權限。而在不同的包中,只有public類可以被訪問。
public 修飾符不只用于定義類的訪問控制級別,也可以應用于接口,方法和變量。public接口同public類一樣,可以由應用程序中的任何類訪問。而public方法或public變量對任何可以訪問他的類或接口都是可視的。
除public 修飾符之外,用于訪問控制的修飾符還有 protected 和private 。 protected或private僅用來定義方法或變量的訪問控制級別。protected方法或protected變量僅對同一個包內的類或不同包中的子類來說是可視的。private方法和private變量對外部定義的類均不可視。需要說明的是,通常不建議用默認方式定義方法或成員變量的訪問級別。

對于沒有指定包名的java源文件,系統認為他們都屬于同一個默認的包。如果沒有把自己的Java類放入某個包中,那么任何默認包里的對象都可以訪問它,并且不局限于同一個子目錄下,因此通常應該在每個Java源文件的項目頂部使用 package語句,指明它所屬的包。
訪問包成員
對于包來說,只有它的public成員可貝外界訪問。若外界想要訪問包的public類,有3種方式可以實現。
(1)通過類的全程限定名訪問該類。
(2)通過import語句導入該類。
(3)通過import語句導入整個包。
如果某個類只貝訪問一次,那么可以直接使用類的全名。例如訪問cn.edu.jmu.graphics.Graphic類可以用一下方式:
cn.edu.jmu.graphics.Graphic aGraph = new cn.edu.jmu.graphics.Graphic();
這條語句創建了 cn.edu.jmu.graphics.Graphic類型的對象 aGraph。
可以看到,即是指創建一個對象,在變量定義和初始化時也用到兩次全名。當使用Java約定的包命名方式時,包名可能過長,此時用起來就更顯得繁瑣,容易出錯,也影響可讀性。
通常都應該使用import語句直接導入所需類,或者導入該類所在的包。導入之后,程序中設計的這個類的地方就可以直接用類名訪問。
import 的基本語法形式為:
import <包名>[.<子包名>].<類名>; //導入指定類
或者:
import <包名>[.<子包名>].*; //導入整個包
例如:
import cn.edu.jmu.javaprogs.Timel;
import cn.edu.jmu.javaprogs.*;
import java.awt.*;
import java.awt.event.*;
import語句在package 語句之后,所有的類聲明之前。由于集中在程序首部,宜于直觀地了解程序所需的包,有助于維護程序的可移植性。
import 語句中的 * 用來匹配包中的所有類,但并不能用來匹配包中的所有類的某個子集。如語句
import java.awt.*;
導入java.awt包中的所有類。如果這樣的語句
import java.awt.A*;
它無法導入java.awt句中首字母為A的所有子類,相反還會出現編譯錯誤,也就是說,使用import語句一次只能導入包的單一成員,或者導入整個包。
還有語句
import java.awt.*;
所導入的是java.awt包中的所有類,它包括接口。但不包括java.awt包中的子包。如果需要訪問java.awt.event子包中的類,仍需要用 import語句導入 java.awt.event子包。所以常常使用如下形式:
import java.awt.*;
import java.awt.event.*;
包的布局
類的全程受名稱與類所在目錄一一對應,例如:
import graphics.Rectangle 等同于文件路徑名:
Graphics\Rectangle.java
classpath參數
classpath參數用于設置Java包所在的頂級目錄。也就是說,通過classpath可以為Java包建立所依存的目錄列表。編譯和運行Java 程序時,系統會自動從classpath環境變量中讀取包所在的目錄,文件所在目錄由系統通過classpath中的目錄和package語句中定義的目錄合成。
下面通過一個完整的實例程序,說明classpath參數的作用,同時展示源文件和字節碼文件的一種建議布局模式。
程序包含兩個類 Time 和 TestTime,TestTime為主類。程序對用戶輸入的表示小時、分鐘和秒鐘的3個整型數,經過數據正確性驗證,分別轉換為通用時間表示格式和標準時間表示格式,通過對話框顯示給用戶,運行后如圖:

文件布局方式如下:創建 d:\javaSample 目錄存放java程序,創建 d:\javaSample\src 子目錄存放源文件,創建d:\javaSample\class 子目錄存放編譯后的字節碼文件。 具體實現方式是將文件 TestTime.java 存放在 D:\javaSample\src 子目錄下,為使 src 子目錄的結構與 class 子目錄結構相對應,創建 D:\javaSample\src\cn\edu\jmu\timer 子目錄存放 Time.java文件。類Time和類TestTime的布局如圖:

Time.java中的語句
package cn.edu.jmu.timer;
將Time類放入包cn.edu.jmu.timer中,源文件Time.java存放在與包相對應的目錄結構下。在類TestTime.java中通過語句 import cn.edu.jmu.timer.Time; 導入Time類。
需要設置classpath參數,規定程序中的包 cn.edu.jmu.timer 編譯所依存的頂級目錄為 d:\javaSample\class,如:
set classpath = d:\javaSample\class;
編譯:
javac -d d:\javaSample\class
d:\javaSample\src\cn\edu\jmu\timer\Time.java
javac -d d:\javaSample\class d:\javaSample\src\TestTime.java
運行:
java TestTime