(初學(xué)者的一些總結(jié)~高手們勿噴哈~) 原因: 以前一直用Eclispe編程環(huán)境運(yùn)行java。非常舒服,就像用傻瓜相機(jī)照相一般。 有看見許多高手都是直接用vim編輯文件,命令行編譯運(yùn)行,覺得那樣不是反而更繁瑣? 轉(zhuǎn)折點(diǎn)是在前幾天本科畢設(shè)題目選定之后。畢設(shè)題是一個(gè)基于java 字節(jié)碼的類關(guān)系動(dòng)態(tài)分析。需要對(duì).class文件中字節(jié)碼進(jìn)行更改(具體的說(shuō)是在許多指令后加入做標(biāo)記的新指令,以實(shí)現(xiàn)動(dòng)態(tài)跟蹤的目的)。 我發(fā)現(xiàn),eclipse根本無(wú)法如此靈活,他無(wú)法直接裝載運(yùn)行一個(gè)我修改過的.class文件。它是照顧大多數(shù)的一般情況。它為我們做了很多事情:自動(dòng)將.java源文件編譯成.class字節(jié)文件,幫我們加載類、運(yùn)行。但卻無(wú)法滿足我個(gè)性化的需求。命令行雖然麻煩,卻是更加本質(zhì)。 至少?gòu)倪@一點(diǎn)上看,java的命令行編譯運(yùn)行還是非常重要的。 我查閱了不少網(wǎng)上資料,發(fā)現(xiàn)資料雖多,卻并不齊全,也不是太清晰。于是整理如下,希望對(duì)初涉java命令行編譯運(yùn)行的筒子有些幫助吧! 許多初學(xué)者編譯運(yùn)行時(shí)候的Exception的發(fā)生,下面的方法都能解決了~如果你遇到什么問題,仔細(xì)看看下面先~說(shuō)不定有所幫助噢。 java的運(yùn)行機(jī)制的基本概念: 源文件 也就是我們熟知的.java文件。 類文件 .class文件是編譯器由.java文件編譯而成。眾所周知,Java的跨平臺(tái)性在于Java虛擬機(jī)(JVM)這一層對(duì)硬件的隔離,而.class文件可以理解為JVM中的執(zhí)行文件(自己的理解,可能不太準(zhǔn)確)。里面存儲(chǔ)的是java字節(jié)碼,java bytecode 是基于棧的(stack based)(關(guān)于字節(jié)碼和JVM更詳細(xì)的官方解釋可以參照 The Java Virtual Machine Specification ,如果嫌那本書太厚,另外再推薦一本 Programming for the Java Virtual Machine)。 編譯 Java的編譯一般是指從源文件(.java文件)到類文件(.class文件)的轉(zhuǎn)化過程。在JDK命令行中是 javac 命令(java compiler的縮寫~跟C語(yǔ)言木關(guān)系的~) 運(yùn)行 在JVM中執(zhí)行.class文件。是 java 命令。 CLASSPATH 環(huán)境變量,存儲(chǔ)著編譯某文件或運(yùn)行某類時(shí),所要搜索的目錄。 比如:在Hello.java中有使用到一個(gè)第三方包ThirdPart.jar中的類,那么必須在classpath中添加相應(yīng)的路徑,讓編譯器能找到它。(注意~把ThirdParty.jar放在當(dāng)前的工作目錄下,沒有告訴環(huán)境變量也是不行的~編譯器只認(rèn)環(huán)境變量的?。┩瑯拥牡览?,在運(yùn)行某類文件時(shí),有涉及到第三方j(luò)ar包的也必須添加到CLASSPATH中。一般的,有三種方式修改環(huán)境變量。 1.在javac 或者java命令中,使用 -classpath 選項(xiàng),后面跟著需要的目錄地址。顯然,這種方法只能在當(dāng)前語(yǔ)句范圍內(nèi)生效。 2.直接命令行修改CLASSPATH或者PATH # PATH=$JAVA_HOME/bin:/home/username/bin #export PATH 不過這種方法只能在此次運(yùn)行中生效。 3.永久生效的方法是修改配置文件。在 /etc/profile 或者 /etc/profile.d 或者其他,不同操作系統(tǒng)發(fā)行版地點(diǎn)不同。在文件中加上CLASSPATH=......(相應(yīng)路徑),重啟電腦即可(也可一執(zhí)行source命令,那樣不用重啟就已經(jīng)生效啦~# source /etc/profile.d 其實(shí) . 跟source是一樣的效果噢~ #. /etc/profile.d ) PATH環(huán)境變量 跟CLASSPATH 類似,只不過它不是用來(lái)尋找類的,而是用來(lái)尋找java相關(guān)執(zhí)行文件的。可以通過 java -version 命令來(lái)查看自己是否已經(jīng)設(shè)置好了PATH(如果顯示了詳細(xì)java信息,則已經(jīng)設(shè)置好了,沒有的話,還需要找到j(luò)ava的安裝位置,重新設(shè)置) 環(huán)境變量的具體相關(guān)信息,參照doc PATH and CLASSPATH 和 Setting the class path。 jar包 java里用package的概念避免重復(fù)命名的問題。有點(diǎn)像C++的namespace。同一個(gè)包里的類是可以直接使用的。不同包的話,則需要在.java文件頭部import進(jìn)對(duì)應(yīng)的package。初學(xué)者寫的helloworld程序當(dāng)然是不用注意到包的問題,但當(dāng)工程越來(lái)越大,重復(fù)命名的可能性增大,我們就必須依靠package的概念來(lái)更好的管理我們的代碼了。 同時(shí),為了方便管理、傳輸,jar包出現(xiàn)了。 jar包其實(shí)是用zip壓縮的文件包。我們可以打包自己的package,方便復(fù)用,到哪果然,也可以直接引用文件夾(此時(shí)注意,必須引用文件夾的根目錄,比如文件定義為package mypackage.foo , 那個(gè)必須將myapackage這個(gè)文件夾連同內(nèi)部的foo文件一起放在相應(yīng)的路徑上) 制作jar壓縮包和解壓縮包的命令如下: 其中最后一個(gè)參數(shù)為需要壓縮的文件包。-cvf幾個(gè)選項(xiàng)中,f必須放在最后,f后面緊跟的必須是output的文件名。v表示輸出詳細(xì)信息(verbose)
對(duì)應(yīng)的解壓縮命令為:
注意其中有個(gè)可選的mainifest文件,在META-INF/MANIFEST.MF路徑上。 我們可以在manifest.mf文件中加入如下語(yǔ)句 Main-Class: myPackage.MyClass指定MyClass類為具有main()入口的主類。再利用如下語(yǔ)句,就可以值執(zhí)行對(duì)應(yīng)的程序了
命令 javac命令:編譯源文件 -classpath 初學(xué)者必須掌握的options ,后接類中使用到的第三方類(形式可以是jar或者zip或者直接就是文件包)的目錄。linux下,多個(gè)目錄用冒號(hào) : 分隔。 值得注意的是,-classpath中的內(nèi)容是會(huì)覆蓋掉環(huán)境變量classpath中的內(nèi)容的~ -cp 是 -classpath的縮寫 -d 制定生成的.class文件存放的目錄。 -o 此選項(xiàng)告訴javac優(yōu)化由內(nèi)聯(lián)的static、final以及privite成員函數(shù)所產(chǎn)生的碼。 還有許多option平時(shí)用的不多(話說(shuō)我也其實(shí)只是剛會(huì)用,并不熟練直接在命令行環(huán)境下的調(diào)試編譯 = =),需要用的時(shí)候直接翻閱 man javac 好了。 java 命令:加載運(yùn)行類文件 -classpath 跟javac中的-classpath同樣的道理。 -cp 也就是 -classpath的縮寫啦。 -jar 執(zhí)行在jar包上定義的主類的程序 一個(gè).java文件的編譯、運(yùn)行示例如下: # javac -classpath ./:/home/username/bin/ThirdParty.jar Hello.java #java -classpath ./:/home/username/bin/ThirdParty.jar Hello 另外,對(duì)于帶有package信息的java文件,執(zhí)行如下:
補(bǔ)充:eclipse的路徑 eclipse下,每個(gè)project都可以控制路徑。 1.在package explorer目錄下,右擊自己的project。下拉菜單中點(diǎn)擊最底部的properties,彈出的窗口的左側(cè),有Java Build Path這一選項(xiàng)卡。 這里主要是對(duì)其他工程包、第三方j(luò)ar包的路徑引入,也有對(duì)project中源文件路徑的設(shè)置。 2.在run的下拉菜單中(就是那個(gè)綠色的Run開始按鈕),選擇Run Configuration. 在每個(gè)運(yùn)行的程序中,都有main、argument、JRE、classpath、source、environment、common這幾個(gè)選項(xiàng)卡。 其中argument里可以設(shè)置java命令行運(yùn)行時(shí)的參數(shù)。也就試main(String[] args)中的args。 classpath里可以設(shè)置system classloader加載類時(shí)的查找目錄。(關(guān)于類的加載,可以參照另幾篇文章 classloader 三原則 和java 類加載器淺析 )
在linux下運(yùn)行時(shí),添加目錄,千萬(wàn)不要弄錯(cuò)分割符。windows下是 \ ,而linux下是 / 。 運(yùn)行類時(shí),不用加.class。比如有一個(gè)類Hello.class,運(yùn)行命令是 # java Hello 而不是 #java Hello.class 。運(yùn)行機(jī)制中是尋找類,而不是像編譯的時(shí)候那樣找到某個(gè)文件。 如果引用的類有package層次,引用的路徑是包層次的起點(diǎn),而不可以延伸到包中的某個(gè)目錄層次。比如引用了~/workspace目錄下的第三方類 com.thirdparty.hello ,在java命令的 -classpath 輸入的是第三方類的包的根目錄所在位置: #java -classpath ~/workspaceHello,而不能是java -classpath ~/workspace/com/thirdparty Hello。 NoSuchMethodException! 在運(yùn)行自己的程序時(shí),遇到了這個(gè)問題。查找了很多資料,最后發(fā)現(xiàn)原來(lái)是路徑問題!原來(lái)的路徑中,一個(gè)老版本的.class文件是在優(yōu)先的位置上,于是每次invoke一個(gè)新寫的method時(shí),就出現(xiàn)這個(gè)錯(cuò)誤 = =。 |
|
來(lái)自: CJOL藏經(jīng)閣 > 《JAVA》