【java基礎(二十)】包

Java允許使用包(package)將類組織起來。藉助包可以方便地組織自己的代碼,並將自己的代碼與別人的代碼庫分開管理。
標準的Java類庫分佈在多個包中,如:java.lang、java.util和java.net等。標準的Java包具有一個層次結構,如果硬盤目錄嵌套一樣,也可以使用嵌套層次組織包。所有標準的Java包都處於java和javax包層次中。
使用包的主要原因是確保類名的唯一性。假如兩個程序猿不約而同地建立了Employee類。只要將這些類放置在不同的包中,就不會產生衝突。事實上,爲了保證包名的絕對唯一性,Sun公司建議將公司的因特網域名以逆序的形式作爲包名,並且對於不同的項目使用不同的自包。
從編譯器的角度看,嵌套的包之間沒有任何關係。如,java.util包與java.util.jar包毫無關係。每一個都擁有獨立的類集合。

類的導入

一個類可以使用所屬包中的所有類,以及其他包中的公有類(public class)。我們可以採用兩種方式訪問另一個包中的共有類。第一種方式是在每個類名之前添加完整的包名。如:

java.time.LocalDate today = java.time.LocalDate.now();

這樣做顯然很繁瑣。更簡單且更常用的方式是使用import語句。import語句是一種引用包含在包中的類的簡明描述。一旦使用 了import語句,在使用類時,就不必寫出包的全名了。
可以使用import語句導入一個特定的類或整個包。import語句應該位於源文件的頂部(但位於package語句的後面)。如:導入java.util保重的所有類時:

import java.util.*;

也可以導入包中的特定類:

import java.time.LocalDate;

// 直接使用類
LocalDate today = LocalDate.now();

java.time.*的語法比較簡單,對代碼的大小也沒有任何負面影響。當然,如果能夠明確地指出導入的類,將會使代碼的讀者更加準確的知道加載了哪些類。
但是,需要注意的是,只能使用星號(*)導入一個包,而不能使用import java.或import java..*導入以java爲前綴的所有包。
在大多數情況下,只導入所需的包,並不必過多地理睬他們。但在發生命名衝突的時候,就不能不注意包的名字了。如:java.util和java.sql包都包含日期(Date)類,如果在程序中導入了這兩個包:

import java.util.*;
import java.sql.*;
// 兩個包都包含名爲Date的類
Date today = new Date(); // 這個時候會出錯,因爲不知道使用哪個包的Date類

如果這兩個Date類都需要使用,要怎麼辦呢?用最原始的方法:

java.util.Date deadline = new java.util.Date();
java.sql.Date today = new java.sql.Date();

在包中定位類是編譯器(compiler)的工作。在類文件(class)的字節碼肯定使用完整的包名來引用其他類。

靜態導入

import語句不僅可以導入類,還增加了導入靜態方法和靜態域的功能。如:

import static java.lang.System.*;

這個時候就可以使用System類的靜態方法和靜態域,而不必加類名前綴:

out.println("hello, world");

另外,還可以導入特定的方法或域:

import static java.lang.System.out;

實際上,是否有更多的程序猿採用System.out或System.exit的簡寫形式,似乎是一件值得懷疑的事情。這種編寫方式不利於代碼的清晰度。
想要將一個類放入包中,就必須將包的名字放在源文件的開頭,包中定義類的代碼之前,如:

package com.horstmann.corejava;

public class Employee {
	...
}

如果沒有在源文件中放置package語句,這個源文件中的類就被放置在一個默認包(default package)中。默認包是一個沒有名字的包。
將包中的文件放到與完整的包名匹配的子目錄中。如,com.horstmann.corejava包中的所有源文件應該被放置在子目錄com\horstmann\corejava中。編譯器將類文件也防災相同的目錄結構。
這時,仍然需要從跟目錄編譯和運行類,如:

javac com\horstmann\corejava\Employee.java
java com.horstmann.corejava.Employee

需要注意,編譯器對文件(帶有文件分隔符和擴展名.java的文件)進行操作。而Java解釋器加載類(帶有.分隔符)。

包作用域

前面已經接觸過訪問修飾符public和private。標記爲public的部分可以被任意的類使用;標記爲private的部分只能被定義它們的類使用。如果沒有指定public或private,這個部分(類、方法或變量)可以被同一個包中的所有方法訪問。
如果沒有將類定義爲公有類或私有類,那麼這個類只有在同一個包(或者默認包)中被其他類訪問,這對於類來說,這種默認是合乎情理的。但是,對於變量來說就有些不適宜了,因此變量必須顯式地標記爲private,不然的話將默認爲包可見,顯然,這樣做會破壞封裝性。

類路徑

類存儲在文件系統的子目錄中。類的路徑必須與包名匹配。
另外,類文件也可以存儲在JAR(Java歸檔)文件中。在一個JAR文件中,可以包含多個壓縮形式的類文件和子目錄,這樣既可以節省又可以改善性能。在程序中用到第三方(third-party)的庫文件時,通常會給出一個或多個需要包含的JAR文件。JDK也提供了許多的JAR文件,如:jre\lib\rt.jar中包含數千個類庫文件。
爲了使類能夠被多個程序共享,需要做到下面幾點:

  1. 把類放到一個目錄中。
  2. 將JAR文件放在一個目錄中。
  3. 設置類路徑(class path)。類路徑是所有包類文件的路徑的集合。

設置類路徑

最好採用-classpath(或-cp)選項指定類路徑:

java -classpath /xx/xxx/xxx Employee

利用-classpath選項設置類路徑是首選的方法。但是,回想一下,我們平時並沒有使用過-classpath,也能正常的編譯執行java程序。這是爲什麼呢?對,是因爲我們在安裝jdk的時候設置了CLASSPATH的環境變量。這樣就默認使用了CLASSPATH中設置的類路徑了。

捐贈

若你感覺讀到這篇文章對你有啓發,能引起你的思考。請不要吝嗇你的錢包,你的任何打賞或者捐贈都是對我莫大的鼓勵。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章