日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

JAVA路徑問題及命令行編譯運行基礎(linux下)

 CJOL藏經(jīng)閣 2013-11-25

(初學者的一些總結(jié)~高手們勿噴哈~)

原因:

以前一直用Eclispe編程環(huán)境運行java。非常舒服,就像用傻瓜相機照相一般。

有看見許多高手都是直接用vim編輯文件,命令行編譯運行,覺得那樣不是反而更繁瑣?

轉(zhuǎn)折點是在前幾天本科畢設題目選定之后。畢設題是一個基于java 字節(jié)碼的類關系動態(tài)分析。需要對.class文件中字節(jié)碼進行更改(具體的說是在許多指令后加入做標記的新指令,以實現(xiàn)動態(tài)跟蹤的目的)。

我發(fā)現(xiàn),eclipse根本無法如此靈活,他無法直接裝載運行一個我修改過的.class文件。它是照顧大多數(shù)的一般情況。它為我們做了很多事情:自動將.java源文件編譯成.class字節(jié)文件,幫我們加載類、運行。但卻無法滿足我個性化的需求。命令行雖然麻煩,卻是更加本質(zhì)。

至少從這一點上看,java的命令行編譯運行還是非常重要的。

我查閱了不少網(wǎng)上資料,發(fā)現(xiàn)資料雖多,卻并不齊全,也不是太清晰。于是整理如下,希望對初涉java命令行編譯運行的筒子有些幫助吧!

許多初學者編譯運行時候的Exception的發(fā)生,下面的方法都能解決了~如果你遇到什么問題,仔細看看下面先~說不定有所幫助噢。


java的運行機制的基本概念:

源文件 也就是我們熟知的.java文件。

類文件  .class文件是編譯器由.java文件編譯而成。眾所周知,Java的跨平臺性在于Java虛擬機(JVM)這一層對硬件的隔離,而.class文件可以理解為JVM中的執(zhí)行文件(自己的理解,可能不太準確)。里面存儲的是java字節(jié)碼,java bytecode 是基于棧的(stack based)(關于字節(jié)碼和JVM更詳細的官方解釋可以參照 The Java Virtual Machine Specification ,如果嫌那本書太厚,另外再推薦一本 Programming for the Java Virtual Machine)。

編譯 Java的編譯一般是指從源文件(.java文件)到類文件(.class文件)的轉(zhuǎn)化過程。在JDK命令行中是 javac 命令(java compiler的縮寫~跟C語言木關系的~)

運行 在JVM中執(zhí)行.class文件。是 java 命令。

CLASSPATH 環(huán)境變量,存儲著編譯某文件或運行某類時,所要搜索的目錄。 比如:在Hello.java中有使用到一個第三方包ThirdPart.jar中的類,那么必須在classpath中添加相應的路徑,讓編譯器能找到它。(注意~把ThirdParty.jar放在當前的工作目錄下,沒有告訴環(huán)境變量也是不行的~編譯器只認環(huán)境變量的?。┩瑯拥牡览?,在運行某類文件時,有涉及到第三方jar包的也必須添加到CLASSPATH中。一般的,有三種方式修改環(huán)境變量。

1.在javac 或者java命令中,使用 -classpath 選項,后面跟著需要的目錄地址。顯然,這種方法只能在當前語句范圍內(nèi)生效。

2.直接命令行修改CLASSPATH或者PATH  # PATH=$JAVA_HOME/bin:/home/username/bin

#export PATH

不過這種方法只能在此次運行中生效。

3.永久生效的方法是修改配置文件。在 /etc/profile 或者 /etc/profile.d 或者其他,不同操作系統(tǒng)發(fā)行版地點不同。在文件中加上CLASSPATH=......(相應路徑),重啟電腦即可(也可一執(zhí)行source命令,那樣不用重啟就已經(jīng)生效啦~# source /etc/profile.d    其實 . 跟source是一樣的效果噢~ #. /etc/profile.d   )

PATH環(huán)境變量 跟CLASSPATH 類似,只不過它不是用來尋找類的,而是用來尋找java相關執(zhí)行文件的??梢酝ㄟ^ java -version 命令來查看自己是否已經(jīng)設置好了PATH(如果顯示了詳細java信息,則已經(jīng)設置好了,沒有的話,還需要找到java的安裝位置,重新設置)

環(huán)境變量的具體相關信息,參照doc   PATH and CLASSPATH 和 Setting the class path。

jar包

java里用package的概念避免重復命名的問題。有點像C++的namespace。同一個包里的類是可以直接使用的。不同包的話,則需要在.java文件頭部import進對應的package。初學者寫的helloworld程序當然是不用注意到包的問題,但當工程越來越大,重復命名的可能性增大,我們就必須依靠package的概念來更好的管理我們的代碼了。

同時,為了方便管理、傳輸,jar包出現(xiàn)了。

jar包其實是用zip壓縮的文件包。我們可以打包自己的package,方便復用,到哪果然,也可以直接引用文件夾(此時注意,必須引用文件夾的根目錄,比如文件定義為package mypackage.foo , 那個必須將myapackage這個文件夾連同內(nèi)部的foo文件一起放在相應的路徑上)

制作jar壓縮包和解壓縮包的命令如下:

 jar -cvf foo.jar foo
其中最后一個參數(shù)為需要壓縮的文件包。-cvf幾個選項中,f必須放在最后,f后面緊跟的必須是output的文件名。v表示輸出詳細信息(verbose)

對應的解壓縮命令為:

 jar -xvf foo.jar

注意其中有個可選的mainifest文件,在META-INF/MANIFEST.MF路徑上。

我們可以在manifest.mf文件中加入如下語句

Main-Class: myPackage.MyClass
指定MyClass類為具有main()入口的主類。再利用如下語句,就可以值執(zhí)行對應的程序了

java -jar foo.jar


命令

javac命令:編譯源文件

-classpath  初學者必須掌握的options ,后接類中使用到的第三方類(形式可以是jar或者zip或者直接就是文件包)的目錄。linux下,多個目錄用冒號 : 分隔。

值得注意的是,-classpath中的內(nèi)容是會覆蓋掉環(huán)境變量classpath中的內(nèi)容的~

-cp 是 -classpath的縮寫

-d  制定生成的.class文件存放的目錄。

-o 此選項告訴javac優(yōu)化由內(nèi)聯(lián)的static、final以及privite成員函數(shù)所產(chǎn)生的碼。 
-verbose 此選項告知Java顯示出有關被編譯的源文件和任何被調(diào)用類庫的信息。比如 -verbose:class 能看到各種類加載的信息。 -verbose:gc是garbage collection的信息。

還有許多option平時用的不多(話說我也其實只是剛會用,并不熟練直接在命令行環(huán)境下的調(diào)試編譯 = =),需要用的時候直接翻閱 man javac 好了。


java 命令:加載運行類文件

-classpath 跟javac中的-classpath同樣的道理。

-cp 也就是 -classpath的縮寫啦。

-jar 執(zhí)行在jar包上定義的主類的程序


一個.java文件的編譯、運行示例如下:

# javac -classpath ./:/home/username/bin/ThirdParty.jar  Hello.java

#java -classpath ./:/home/username/bin/ThirdParty.jar  Hello    


另外,對于帶有package信息的java文件,執(zhí)行如下:

$ ls .                   # Current directory contains the "x" package
x

$ ls x                   # The "x" package contains a Sample.java file...
Sample.java

$ cat x/Sample.java      # ...which looks like this.
package x;
public class Sample {
    public static void main(String... args) {
        System.out.println("Hello from Sample class");
    }
}

$ javac x/Sample.java    # Use "/" as delimiter and
                         # include the ".java"-suffix when compiling.

$ java x.Sample          # Use "." as delimiter when running, and don't include
                         # the ".class" suffix.
Hello from Sample class


補充:eclipse的路徑

eclipse下,每個project都可以控制路徑。

1.在package explorer目錄下,右擊自己的project。下拉菜單中點擊最底部的properties,彈出的窗口的左側(cè),有Java Build Path這一選項卡。

這里主要是對其他工程包、第三方jar包的路徑引入,也有對project中源文件路徑的設置。

2.在run的下拉菜單中(就是那個綠色的Run開始按鈕),選擇Run Configuration.

在每個運行的程序中,都有main、argument、JRE、classpath、source、environment、common這幾個選項卡。

其中argument里可以設置java命令行運行時的參數(shù)。也就試main(String[] args)中的args。

classpath里可以設置system classloader加載類時的查找目錄。(關于類的加載,可以參照另幾篇文章 classloader 三原則java 類加載器淺析




雷區(qū): 

在linux下運行時,添加目錄,千萬不要弄錯分割符。windows下是 \ ,而linux下是 / 。

運行類時,不用加.class。比如有一個類Hello.class,運行命令是 # java  Hello 而不是 #java Hello.class 。運行機制中是尋找類,而不是像編譯的時候那樣找到某個文件。

如果引用的類有package層次,引用的路徑是包層次的起點,而不可以延伸到包中的某個目錄層次。比如引用了~/workspace目錄下的第三方類 com.thirdparty.hello ,在java命令的 -classpath 輸入的是第三方類的包的根目錄所在位置: #java -classpath ~/workspaceHello,而不能是java -classpath ~/workspace/com/thirdparty  Hello。




NoSuchMethodException! 

在運行自己的程序時,遇到了這個問題。查找了很多資料,最后發(fā)現(xiàn)原來是路徑問題!原來的路徑中,一個老版本的.class文件是在優(yōu)先的位置上,于是每次invoke一個新寫的method時,就出現(xiàn)這個錯誤 = =。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多