Java初學者 JDK命令行 路徑問題_第1頁
Java初學者 JDK命令行 路徑問題_第2頁
Java初學者 JDK命令行 路徑問題_第3頁
Java初學者 JDK命令行 路徑問題_第4頁
Java初學者 JDK命令行 路徑問題_第5頁
已閱讀5頁,還剩8頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、Java初學者 JDK命令行 路徑問題.txt我自橫刀向天笑,笑完我就去睡覺。 你的手機比話費還便宜。路漫漫其修遠兮,不如我們打的吧。Java初學者 JDK命令行 路徑問題屏幕出現:Exception in thread "main" java.lang.NoClassDefFoundError: C:JavaTestHellohello.class明明在為什么說CLASS不在,原因在CLASSPATH 1、SET CLASSPATH=、2、JAVA -CLASSPATH C:、JDK將帶有空格的C:Java Test分隔為兩部分"C:Java"及&qu

2、ot;TestHello.java",并將C:Java視作為一個無效的選項了。這種情況下,我們需要將整個路徑都加上雙引號,即javac "C:Java TestHello.java"這回JDK知道,引號里面的是一個完整的路徑,因此就不會報錯了。同樣,對java命令也需要如此,即java -classpath "C:Java Test" Hello Java很誘人,但對于剛跨入Java門檻的初學者來說,編譯并運行一個無比簡單的Java程序簡直就是一個惡夢。明明程序沒錯,但各種各樣讓人摸 不著頭腦的錯誤信息真的讓你百思不得其解,許多在Java門口徘

3、徊了很久的初學者就這樣放棄了學習Java的機會,很是可惜。筆者也經歷過這個無比痛苦的 階段,感覺到編譯難的問題就出在classpath的設置及對package的理解之上。本文以實例的方式,逐一解決在編譯過程中所出現的各種 classpath的設置問題。本文實例運行的環境是在Windows XP + JDK 1.5.0。對其他的環境,讀者應該很容易進行相應的轉換。1. 下載并安裝JDK1.5.0,并按默認路徑,安裝到C:Program FilesJavajdk1.5.0中。2. 用鼠標單擊WindowsXP的“開始”->“運行”,在彈出的運行窗口中輸入cmd,按確定或回車,打開一個命令行窗

4、口。3. 在命令行中輸入:java有一列長長的洋文滾了出來,這是JDK告訴我們java這個命令的使用方法。其中隱含了一個重要信息,即JDK安裝成功,可以在命令行中使用java此命令了。4. 在命令行中輸入javac屏幕顯示:'javac' 不是內部或外部命令,也不是可運行的程序或批處理文件。這 是由于windows找不到javac這個命令的原因。這就不明白了,java與javac都是JDK在同一個子目錄里面的兩個文件,為什么可以直接運行 java而不能直接運行javac呢?原來,Sun公司為了方便大家在安裝完JDK后馬上就可以運行Java類文件,在后臺悄悄地將j

5、ava命令加入了 Path的搜索路徑中,因此我們可以直接運行java命令(但我們是看不到它到底是在哪設置的,無論是在用戶的Path或系統的Path設置中均找不到這 個java存放的路徑)。但Sun所做的到此為止,其他JDK的命令,一概不管,需要由用戶自己添加到搜索路徑中。5. 既然如此,那我們自己添加Path的搜索路徑吧。對“我的電腦”按右鍵,選“屬性”,在“系統屬性”窗口中選“高級”標簽,再按“環境變量”按鈕,彈出一 個“環境變量”的窗口,在用戶變量中新建一個變量,變量名為“Path”,變量值為"C:Program FilesJavajdk1.5.0bin;%PATH%"

6、。最后的%PATH%的意思是說,保留原有的Path設置,且將目前的Path設置新加 到其前面。一路按“確定”退出(共有3次)。關掉原來的命令行窗口,依照第2步,重新打開一個新的命令行窗口。在此窗口中輸入javac長長的洋文又出現了,這回是介紹javac的用法。設置成功。6. So far so good. 到目前為止,我們已經可以編程了。但是,這不是一個好辦法。因為隨著以后我們深入學習Java,我們就會用到JUnit、Ant或NetBeans等應用 工具,這些工具在安裝時,都需要一個名為指向JDK路徑的“JAVA_HOME”的環境變量,否則就安裝不了。因此,我們需要改進第5步,為以后作好準 備

7、。依照第5步,彈出“環境變量”的窗口,在用戶變量中新建一個變量,變量名為“JAVA_HOME”,變量值為"C:Program FilesJavajdk1.5.0"。注意,這里的變量值只到jdk1.5.0,不能延伸到bin中。確定后,返回“環境變量”的窗口,雙擊我們原 先設定的Path變量,將其值修改為“%JAVA_HOME%bin;%PATH%”。這種效果與第5步是完全一樣的,只不過多了一個 JAVA_HOME的變量。這樣,以后當我們需要指向JDK的路徑時,只需要加入“%JAVA_HOME%”就行了。至此,Path路徑全部設置完畢。一 路確定退出,打開新的命令行窗口,輸入j

8、avac如果長長的洋文出現,Path已經設置正確,一切正常。如果不是,請仔細檢查本步驟是否完全設置正確。7. 開始編程。在C盤的根目錄中新建一個子目錄,名為“JavaTest”,以作為存放Java源代碼的地方。打開XP中的記事本,先將其保存到 JavaTest文件夾中,在“文件名”文本框中輸入"Hello.java"。注意,在文件名的前后各加上一個雙引號,否則,記事本就會將其存 為"Hello.java.txt"的文本文件。然后輸入以下代碼:public class Hello public static void main(String args) S

9、ystem.out.println("Hello, world");再次保存文件。8. 在命令行窗口中輸入cd C:JavaTest將當前路徑轉入JavaTest中。然后,輸入javac Hello.javaJDK 就在JavaTest文件夾中編譯生成一個Hello.class的類文件。如果出現“1 error”或“XX errors”的字樣,說明是源代碼的輸入有誤,請根據出錯提示,仔細地按第7步的代碼找出并修正錯誤。請讀者注意甄別代碼輸入有誤的問題與 classpath設置有誤的問題。因為本文是關于如何正確設置classpath及package的,因此,這里假設讀者輸入的

10、代碼準確無誤。到目前為 此,由于我們是在源代碼的當前路徑下編譯,因此,不會出現classpath設置有誤的問題。9. 在命令行窗口中輸入java Hello屏幕出現了Hello world成功了,我們已經順利地編譯及運行了第一個Java程序。但 是,第8步及第9步是不完美的,因為我們是在JavaTest這個存放源碼的文件夾中進行編譯及運行的,因此,一些非常重要的問題并沒有暴露出來。實際 上,第8步的“javac Hello.java”及第9步的“java Hello”涉及到兩個問題,一是操作系統如何尋找“javac”及“java”等命令,二是操作系統如何尋找“Hello.java”及 “Hel

11、lo.class”這些用戶自己創建的文件。對于“javac”及“java”等命令,由于它們均是可執行文件,操作系統就會依據我們在第6步中 設置好的Path路徑中去尋找。而對于“Hello.java”及“Hello.class”這些文件,Path的設置不起作用。由于我們是在當前工作路 徑中工作,java及javac會在當前工作路徑中尋找相應的java文件(class文件的尋找比較特殊,詳見第11步),因此一切正常。下面我們開始人為地將問題復雜化,在非當前工作路徑中編譯及運行,看看結果如何。10. 在命令行窗口中輸入cd C:轉入到C盤根目錄上,當前路徑離開了存放源碼的工作區。輸入javac He

12、llo.java屏幕出現:error: cannot read: Hello.java1 error找不到Hello.java了。我們要給它指定一個路徑,告訴它到C:JavaTest去找Hello.java文件。輸入javac C:JavaTestHello.javaOK,這回不報錯了,編譯成功。11. 輸入java C:JavaTestHello這回屏幕出現:Exception in thread "main" java.lang.NoClassDefFoundError: C:JavaTestHello意 思為在“C:JavaTestHello”找不到類的定義。明明C:

13、JavaTestHello是一個.class文件,為什么就找不到呢?原 來,Java對待.java文件與.class文件是有區別的。對.java文件可以直接指定路徑給它,而java命令所需的.class文件不能出現擴 展名,也不能指定額外的路徑給它。那么,如何指定路徑呢?對于Java所需的.class文件,必須通過classpath來指定。12. 依照第5步,彈出“環境變量”窗口,在用戶變量中新建一個變量,變量名為“classpath”,變量值為"C:JavaTest"。一路按“確定”退出。關閉原命令行窗口,打開新的命令行窗口,輸入java Hello“Hello worl

14、d”出來了。由此可見,在“環境變量”窗口中設置classpath的目的就是告訴JDK,到哪里去尋找.class文件。這種方法一旦設置好, 以后每次運行java或javac時,在需要調用.class文件時,JDK都會自動地來到這里尋找。因此,這是一個全局性的設置。13. 除了這種在環境變量”窗口中設置classpath的方法之外,還有另一種方法,即在java命令后面加上一個選項classpath,緊跟著不帶擴展名的class文件名。例如,java -classpath C:JavaTest HelloJDK 遇到這種情況時,先根據命令行中的classpath選項中指定的路徑去尋找.class文件

15、,找不到時再到全局的classpath環境變量中去尋找。 這種情況下,即使是沒有設置全局的classpath環境變量,由于已經在命令行中正確地指定類路徑,也可以運行。為了在下面的例子中更好地演示classpath的問題,我們先將全局的classpath環境變量刪除,而在必要時代之以命令行選項-classpath。彈出“環境變量”窗口,選中“classpath”的變量名,按“刪除”鍵。此 外,java命令中還可以用cp,即classpath的縮寫來代替classpath,如java -cp C:JavaTest Hello。特別注意的是,JDK 1.5.0之前,javac命令不能用cp來代替cl

16、asspath,而只能用classpath。而在JDK 1.5.0中,java及javac都可以使用cp及classpath。因此,為保持一致,建議一概使用classpath作為選項名稱。14. 我們再次人為地復雜化問題。關閉正在編輯Hello.java的記事本,然后將JavaTest文件夾名稱改為帶空格的“Java Test”。在命令行中輸入javac C:Java TestHello.java長長的洋文又出來了,但這回卻是報錯了:javac: invalid flag: C:JavaJDK將帶有空格的C:Java Test分隔為兩部分"C:Java"及"Tes

17、tHello.java",并將C:Java視作為一個無效的選項了。這種情況下,我們需要將整個路徑都加上雙引號,即javac "C:Java TestHello.java"這回JDK知道,引號里面的是一個完整的路徑,因此就不會報錯了。同樣,對java命令也需要如此,即java -classpath "C:Java Test" Hello對于長文件名及中文的文件夾,XP下面可以不加雙引號。但一般來說,加雙引號不容易出錯,也容易理解,因此,建議在classpath選項中使用雙引號。15. 我們再來看.java文件使用了其他類的情況。在C:Java T

18、est中新建一個Person.java文件,內容如下:public class Person private String name;public Person(String name) = name;public String getName() return name;然后,修改Hello.java,內容如下:public class Hello public static void main(String args) Person person = new Person("Mike");System.out.println(person.getNa

19、me();在命令行輸入javac "C:Java TestHello.java"錯誤來了:C:Java TestHello.java:3: cannot find symbolsymbol: class PersonJDK 提示找不到Person類。為什么javac "C:Java TestHello.java"在第14步中可行,而在這里卻不行了呢?第14步中的Hello.java文件并沒有用來其他類,因此,JDK不需要去 尋找其他類,而到了這里,我們修改了Hello.java,讓其使用了一個Person類。根據第11步,我們需要告訴JDK,到哪里去找所

20、用到的類,即 使這個被使用的類就與Hello.java一起,同在C:Java Test下面!輸入javac -classpath "C:Java Test" "C:Java TestHello.java"編 譯通過,JDK在C:Java Test文件夾下同時生成了Hello.class及Person.class兩個文件。實際上,由于Hello.java使用了Person.java 類,JDK先編譯生成了Person.class,然后再編譯生成Hello.class。因此,不管Hello.java這個主類使用了多少個其他類, 只要編譯這個類,JDK就會自動

21、編譯其他類,很方便。輸入java -classpath "C:Java Test" Hello屏幕出現了Mike成功。16. 第15步說明了在Hello.java中如何使用一個我們自己創建的Person.java,而且這個類與Hello.java是同在一個文件夾下。在這一步中,我們將考查Person.java如果放在不同文件夾下面的情況。先將C:Java Test文件夾下的Person.class文件刪除,然后在C:Java Test文件夾下新建一個名為DF的文件夾,并將C:Java Test文件夾下的Person.java移動到其下面。在命令行輸入javac -class

22、path "C:Java TestDF" "C:Java TestHello.java"編譯通過。這時javac命令沒有什么不同,只需將classpath改成C:Java TestDF就行了。在命令行輸入java -classpath "C:Java Test" Hello這時由于Java需要找在不同文件夾下的兩個.class文件,而命令行中只告訴JDK一個路徑,即C:Java Test,在此文件夾下,只能找到Hello.class,找不到Person.class文件,因此,錯誤是可以預料得到的:Exception in thread

23、 "main" java.lang.NoClassDefFoundError: Personat Hello.main(Hello.java:3)果真找不到Person.class。在設置兩個以上的classpath時,先將每個路徑以雙引號引起來,再將這些路徑以“;”號隔開,并且每個路徑與“;”之間不能帶有空格。因此,我們在命令行重新輸入:java -classpath "C:Java Test""C:Java TestDF" Hello編 譯成功。但也暴露出一個問題,如果我們需要用到許多分處于不同文件夾下的類,那這個classpat

24、h的設置豈不是很長!有沒有辦法,對于一個文件夾下的 所有.class文件,只指定這個文件夾的classpath,然后讓JDK自動搜索此文件夾下面所有相應的路徑?有,只要使用package。17. package簡介。Java中引入package的概念,主要是為了解決命名沖突的問題。比如說,在我們的例子中,我們設計了一個很簡單的Person 類,如果某人開發了一個類庫,其中恰巧也有一個Person類,當我們使用這個類庫時,兩個Person類出現了命名沖突,JDK不知道我們到底要使用哪 個Person類。更有甚者,當我們也開發了一個很龐大的類庫,無可避免地,我們的類庫中與其他人開發的類庫中命名沖突

25、的情況就會越來越多。總不能為了避 免自己的類名與其他人開發的類名相同,而讓每個編程人員都絞盡腦汁地將一個本應叫Writer的類強行改名為 SarkuyaWriter,MikeWriter, SmithWriter吧?現實生活中也是如此。假如你名叫張三,又假如與你同一 單位的人中有好幾個都叫張三,那你的問題就來了。某天單位領導在會上宣布,張三被任命為辦公室主任,你簡直不知道是該哭還是該笑。但如果你的單位中只有你 叫張三,你才不會在乎全國叫張三的人有多少個,因為其他張三都分布在全國各地、其他城市,你看不見他們,摸不著他們,自然不會擔心。Sun 從這個“張三問題”受到了很大的啟發,為解決命名沖突問題

26、,就采取了“眼不見心不煩”的策略:將每個類都歸屬到一個特定的區域中,在同一個區域中的所有 類,都不允許同名;而不同區域的類,由于相互看不到,則允許有同名的類存在。這樣,就解決了命名沖突的問題,正如北京的張三與上海的張三畢竟不是同一人。 這個區域在Java中就叫package。由于package在Java中非常重要,如果你沒有定義自己的package,JDK將會你的類都歸到一個默 認的無名package中。自定義package的名稱可以由各個程序員自由創建。作為避免命名沖突的手段,package的名稱最好足 以與其他程序員的區別開來。在互聯網上,每個域名都是唯一的,因此,Sun推薦將你自己的域名

27、倒寫后作為package的名稱。如果你沒有自己的域名,很 可能只是因為囊中羞澀而不去申請罷了,并不見得你假想的域名與其他域名發生沖突。例如,筆者假想的域名是,目前就是唯一的,因此我 的package就可以定名為com.sarkuya。謝謝Java給了我們一個免費使用我們自己域名的機會,唯一的前提是倒著寫。當然,每個 package下面還可以帶有不同的子package,如com.sarkuya.util,com.sarkuya.swing,等等。定 義package的方式是在相應的.java文件的第一行加上“package packagename;”的字樣,而且每個.java文件只能有一個pac

28、kage。實際上,Java中的package的實現是與計算機文件系統相結 合的,即你有什么樣的package,在硬盤上就有什么樣的存放路徑。例如,某個類的package名為com.sarkuya.util,那么,這個類 就應該必須存放在com/sarkuya/util的路徑下面。至于這個com/sarkuya/util又是哪個文件夾的子路徑,第18步會談到。package除了有避免命名沖突的問題外,還引申出一個保護當前package下所有類文件的功能,主要通過為類定義幾種可視度不同的修飾符來實現:public, protected, private, 另外加上一個并不真實存在的friendly

29、類型。對于冠以public的類、類屬變量及方法,包內及包外的任何類均可以訪問;protected的類、類屬變量及方法,包內的任何類,及包外的那些繼承了此類的子類才能訪問;private的類、類屬變量及方法,包內包外的任何類均不能訪問;如果一個類、類屬變量及方法不以這三種修飾符來修飾,它就是friendly類型的,那么包內的任何類都可以訪問它,而包外的任何類都不能訪問它(包括包外繼承了此類的子類),因此,這種類、類屬變量及方法對包內的其他類是友好的,開放的,而對包外的其他類是關閉的。前 面說過,package主要是為了解決命名沖突的問題,因此,處在不同的包里面的類根本不用擔心與其他包的類名發生沖

30、突,因為JDK在默認情況下只使用本 包下面的類,對于其他包,JDK一概視而不見:“眼不見心不煩”。如果要引用其他包的類,就必須通過import來引入其他包中相應的類。只有在這 時,JDK才會進行進一步的審查,即根據其他包中的這些類、類屬變量及方法的可視度來審查是否符合使用要求。如果此審查通不過,編譯就此卡住,直至你放棄 使用這些類、類屬變量及方法,或者將被引入的類、類屬變量及方法的修飾符改為符合要求為止。如果此審查通過,JDK最后進行命名是否沖突的審查。如果發現 命名沖突,你可以通過在代碼中引用全名的方式來顯式地引用相應的類,如使用java.util.Date = new java.util.

31、Date()或是java.sql.Date = new java.sql.Date()。package的第三大作用是簡化classpath的設置。還記得第16步中的障礙嗎?這里重新引用其java命令:java -classpath "C:Java Test""C:Java TestDF" Hello我 們必須將所有的.class文件的路徑一一告訴JDK,而不管DF其實就是C:Java Test的子目錄。如果要用到100個不同路徑的.class文件,我們就得將classpath設置為一個特別長的字符串,很累。package的引 入,很好地解決了這個問題。p

32、ackage的與classpath相結合,通過import指令為中介,將原來必須由classpath完成的類路徑搜索 功能,很巧妙地轉移到import的身上,從而使classpath的設置簡潔明了。我們先看下面的例子。18. 先在Hello.java中導入DF.Person。代碼修改如下:import DF.Person;public class Hello public static void main(String args) Person person = new Person("Mike");System.out.println(person.getName();再

33、將DF子文件夾中的Person.java設置一個DF包。代碼修改如下:package DF;public class Person private String name;public Person(String name) = name;public String getName() return name;好了,神奇的命令行出現了:javac -classpath "C:Java Test" "C:Java TestHello.java"java -classpath "C:Java Test" Hello盡管

34、這次我們只設置了C:Java Test的classpath,但編譯及運行居然都通過了!事實上,Java在搜索.class文件時,共有三種方法:一是全局性的設置,詳見第12步,其優點是一次設置,每次使用;二是在每次的javac及java命令行中自行設置classpath,這也是本文使用最多的一種方式,其優點是不加重系統環境變量的負擔;三 是根據import指令,將其內容在后臺轉換為classpath。JDK將讀取全局的環境變量classpath及命令行中的classpath選項信 息,然后將每條classpath與經過轉換為路徑形式的import的內容相合并,從而形成最終的classpath.

35、在我們的例子中,JDK讀取全局的環境變量classpath及命令行中的classpath選項信息,得到C:Java Test。接著,將import DF.Person中的內容,即DF.Person轉換為DFPerson, 然后將C:Java Test與其合并,成為C:Java TestDFPerson,這就是我們所需要的Person.class的路徑。在Hello.java中有多少條import語句,就自動進行多少 次這樣的轉換。而我們在命令行中只需告訴JDK最頂層的classpath就行了,剩下的則由各個類中的import指令代為操勞了。這種移花接木的作法 為我們在命令行中手工地設置clas

36、spath提供了極大的便利。應注意的一點是,import指令是與package配套使用的,只有在某類通過“package pacakgename;”設定了包名后,才能給其他類通過import指令導入。如果import試圖導入一個尚未設置包的類,JVM就會報錯。19. 我們接下來看,當使用JDK類庫時,classpath如何設置。20. 修改Hello.java,內容如下:import DF.Person;import java.util.Date;public class Hello public static void main(String args) Date date = new Da

37、te();System.out.println(date);Person person = new Person("Mike");System.out.println(person.getName();21. JDK類庫存放于C:Program FilesJavajdk1.5.0jrelibrt.jar文件中。關于jar文件的介紹,已經超出了本文的范圍,感興趣的讀者可以閱讀Horstmann寫的Core Java一書。jar 文件可以用WinRar打開。用WinRar打開后,可以看到里面有一些文件夾,雙擊其中的java文件夾,再雙擊util的文件夾,可以在看到 Date.c

38、lass文件就在其中。如果你看過Data.java或其他JDK類庫的源碼(在C:Program FilesJavajdk1.5.0src.zip文件中),你就會發現,像java、util這些文件夾均是package。這也是 Hello.java第2行中使用了import指令的原因。我們可以通過WinRar的查找功能來定位某個類所在的包。在“查找文件” 的窗口中的“要查找的文件名”文本框中輸入Date.class,就會查找出在rt.jar文件中存在兩個Date.class文件,一個是 javasqlDate.class,另一個是javautilDate.class。其中,sql下面的Date.c

39、lass文件與數據庫有 關,并非我們這里所需,javautilDate.class才是我們所要的。rt.jar文件就像本文中的C:Java Test中一樣,是JDK類庫的唯一入口。我們可以在命令行的classpath選項指定.jar文件。需要注意,.jar文件的classpath設置 有些特珠。在以前的例子中,我們設置classpath時都是設置了路徑就行了,而對于.jar文件,我們必須將.jar文件名直接加到 classpath中。22. 在命令行輸入javac -classpath "C:Program FilesJavajdk1.5.0jrelibrt.jar""C:Java Test" "C:Jav

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論