深入理解PATH CLASSPATH

轉帖:http://tieba.baidu.com/f?kz=293706722

 

認識PATH

如果你使用過 DOS或者 Linux這樣的字符界面的操作系統,相信你對PATH已 經有了一定的瞭解。而現在的朋友們幾乎連 DOS都沒有用過,都是在MS的圖形窗 口下長大的,對PATH的認識遠沒有當年苦背 DOS命令的一代深刻了。

PATH,也就是路徑。我們所使用的操作系統一般都是樹形目錄結構,例如我 正在使用的WinXP系統,在系統的最上級目錄有C:,D:,E: 目錄,在C:下又有許 多目錄和文件:

可以看出是樹形結構了吧?:), 當我們描述一個文件的位置時,就要用到路徑了。比如,Windows目錄在哪裏?你會很快的 說:C:/Windows/,那notepad.exe 文件在哪裏?你找了一會兒回答說:C:/WINDOWS/notepad.exe。 right! 這些就 是路徑。

路徑是指從樹型目錄中的某個目錄層次到某個文件的一條道路。和物理上的 路徑是一樣的,如同你從實驗室回到寢室的路,就是一條路徑,順着路徑,你可 以找到你要找到的東西,當然,這個東西一定要在路徑上。

在對文件進行訪問時,要給出文件所在的路徑。 路徑又分相對路徑和絕對路 徑。 絕對路徑是指從"根"開始的路徑;相對路徑是從用戶工作目錄開始的路徑。

比如你現在在A樓工作,有人問你廁所在哪裏?你說:隔壁。
這個隔壁就是相對路徑,是相對於你現在所在的位置所說

如果別人要問你: 你家是哪裏的?你會說,內蒙古赤峯阿旗。
這裏的內蒙古赤峯阿旗就是絕對位置。 當然,這時默認的根是中國,否則就說:..... 銀河系太陽系地球..... :)

現在你應該知道什麼是PATH也就是路徑了吧?

接下來,說一說系統的環境變量裏面的PATH是幹什麼用的。

按照上節所述的方法查看環境變量(提示一下,Win98系統看C:/autoexec.bat WinNT、Win2K、WinXP系統:控制面 板-〉系統-〉高級-〉環境變量,Linux系統爲 /etc/profile),你會發現有一個名爲PATH的東西,他的值爲:


%SystemRoot%/system32;%SystemRoot%;%SystemRoot%/System32/Wbem


注意:不可能完全一樣,但是可能完全不一樣,相信自己,你找對了,這就是PATH。

這個PATH是幹什麼用的呢?例如,我經常使用C:/Windows/notepad.exe這個文件。如果在命令行模式下(因爲在命令行下你猜 可以看得到,如果用鼠標,你根本看不到調用了哪些東西),現在我在D:/,我想用notepad.exe打開D:/a.txt 那麼,我要使用和命令:


D:/>C:/Windows/notepad.exe a.txt 


如果頻繁的使用這個notepad.exe,我一直都要敲入C:/Windows/notepad.exe 再加上我的打字速度不快,還一直擔心打太多的字會損害指關節,於是我決定偷懶。我將上面的PATH改爲:

%SystemRoot%/system32;%SystemRoot%;%SystemRoot%/System32/Wbem;C:/Windows/ 

注意我後面加的東西,這樣我就可以這樣來使用D:/>C:/Windows/notepad.exe了

D:/>notepad.exe a.txt 


是不是很方便呀?如果C:/Windows/notepad.exe的路徑更長,偷懶的效果就 更明顯了!:)。

當我們敲入notepad.exe的時候,系統首先在當前目錄尋找notepad.exe,結 果沒找到,於是在系統的環境變量PATH裏面尋找:
%SystemRoot%/system32/notepad.exe 沒找到
%SystemRoot%/notepad.exe 沒找到
%SystemRoot%/System32/Wbem/notepad.exe 沒找到
C:/Windows/notepad.exe 找到啦~,於是調用此文件~!

現在明白環境變量PATH的作用了吧?:)

如果你已經按照上篇理解了PATH,那麼接下來對 CLASSPATH的理解就順理成 章了。

因爲我們可愛的Java要實現跨平臺,而每個平臺的文件的路徑的表示方法是 不一樣的,所以呢,Java就不能使用具體的操作系統提供的PATH 了,可是Java還要需要調用不同的文件 (這裏所說的文件是Java的文件,在寫Java程序的時候, 我們不能把所有的代碼寫到一個文件裏吧?),那 怎麼辦呢?

於是,有人想出辦法,每個系統不是有PATH來提供文件的檢索嗎?我們的jvm (還知道jvm是什麼嗎?如果忘記了,看前面) 不就是一個邏輯 意義上的平臺嗎? 那麼,我們就可以定義另外一種路徑來提供文件的檢索呀?於是 CLASSPATH就誕生了!因爲所有的Java文件到頭來都是 CLASS文件(都是*.class),所以這個PATH 就是CLASS的PATH,也就是CLASSPATH啦~。

 

說到這裏,你應該明白原來 CLASSPATH像系統裏面的PATH一樣,都是一種路 徑系統裏的PATH的路徑是提供系統裏面文件的檢索, CLASSPATH是在Java虛擬機 工作的時候提供對CLASS的檢索。

既然已經決定創造出一個CLASSPATH出來,那麼該怎麼實現這個CLASSPATH呢?當然還是不能脫離具體的操作系統,巧婦難爲無米之炊, 我們建不出空中樓閣。 PATH挺像我們需要的 CLASSPATH的,那麼我們就把PATH加工一下或者改造一下, 當作我們需要的東西來用吧。事實上 也是這麼做的。

於是我們在系統的環境變量裏面添加一個新的變量叫 CLASSPATH。他的描述方法用PATH的描述方法:

.;D:/classes/;D:/j2sdk1.4.2b/lib/dt.jar;D:/j2sdk1.4.2b/lib/tools.jar 


可以看到,新的變量 CLASSPATH使用的系統的路徑表示的(例如D:/classes/ 就是一個系統的路徑),但是不能用環境環境變量PATH,所以不能寫成:

%Path%;D:/classes/;D:/j2sdk1.4.2b/lib/dt.jar;D:/j2sdk1.4.2b/lib/tools.jar 

或者

$Path;D:/classes/;D:/j2sdk1.4.2b/lib/dt.jar;D:/j2sdk1.4.2b/lib/tools.jar  

這樣當jvm想要調用Java文件(class文件)的時候,不能通過PATH尋找,只能 從CLASSPATH尋找了。

讓我們看一個例子:

D:/JavaTest>javac HelloWorld.java  


這一步的執行過程是:

1.系統發現啓動的程序是javac,於是開始尋找javac.exe。 尋找的次序按照上篇所述尋找notepad.exe的順序雷同

2.找到之後,運行javac.exe,附加參數HelloWorld.java

3.javac編譯HelloWorld.java -> HelloWorld.class
如果HelloWorld.java中有其他類庫(類庫就是分類整理好的一堆class 文件)的引用,例如:

import java.io.*; 
import com.hdpan.util.*; 

對於標準類庫的引用,像上面的"java.io.*",可以直接使用,也就是說它 不需要顯示的放在系統的環境變量CLASSPATH中。

而對於非標準類庫,像"com.hdpan.util.*",javac怎麼來找到它呢? 上面說了,它是通過系統的環境變量CLASSPATH來找:讓我們再回顧一下我 們的CLASSPATH是如何設定的:

.;D:/classes/;D:/j2sdk1.4.2b/lib/dt.jar;D:/j2sdk1.4.2b/lib/tools.jar 

然後再看看當前的目錄結構:

首先找到D:/JavaTest/HelloWorld.java,這個是我們正在編譯的文件,接 下來,我們來看看javac是怎麼來尋找net.eastdawn.util.*的:

發現是非標準類庫,開始搜索CLASSPATH,第一個CLASSPATH是".",也就是當前目錄,當前目錄有一個net文件夾,然後 eastdawn,可是eastdawn文件夾下面沒有util文件夾,於是第一個CLASSPATH搜索失敗。然後搜索第二個 CLASSPATH "D:/classes/",果然再此發現了net/eastdawn/util/,於是這裏編譯通過。

至此,D:/JavaTest>javac HelloWorld.java 執行完畢。

現在也應該明白爲什麼在CLASSPATH的前面會有一個 "."了吧?他就是爲了優先 搜索當前目錄下的class。

運行完javac之後,當前目錄多一個文件:HelloWorld.class,運行它:

D:/JavaTest>java HelloWorld  

(注意:是java HelloWorld,而不是java HelloWorld.class)

這裏用到了java命令,所以啓動一個jvm(jvm是什麼?看前面的文章吧,:)), 開始搜索CLASSPATH,首先按照"."搜索,在當前目錄找到了HelloWorld.class, 於是運行!

現在你明白了爲什麼許多人別寫了HelloWorld卻在運行的時候出現這個了吧:


Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld  

你想對了,就是因爲jre不能根據CLASSPATH來找到HelloWorld.class,哪怕HelloWorld.class就在當前目 錄,當時環境變量的CLASSPATH裏沒有 "."這個設定,同樣是找不到!哈哈,java怎麼這麼笨啊~,是很笨的,那麼,聰明的我們 就不要再犯這 樣的錯誤嘍~。
然後呢,一大堆的問題你都應該可以解決了,比如頻繁出現的
NoClassDefFoundError、class not found、.....


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