若是是用Exlipse, 第三方的包能夠放在eclipse文件夾的jre包的lib文件夾中!
(初學者的一些總結~高手們勿噴哈~)html
緣由:java
之前一直用Eclispe編程環境運行Java。很是舒服,就像用傻瓜相機照相通常。linux
有看見許多高手都是直接用vim編輯文件,命令行編譯運行,以爲那樣不是反而更繁瑣?編程
轉折點是在前幾天本科畢設題目選定以後。畢設題是一個基於java 字節碼的類關係動態分析。須要對.class文件中字節碼進行更改(具體的說是在許多指令後加入作標記的新指令,以實現動態跟蹤的目的)。vim
我發現,eclipse根本沒法如此靈活,他沒法直接裝載運行一個我修改過的.class文件。它是照顧大多數的通常狀況。它爲咱們作了不少事情:自動將.java源文件編譯成.class字節文件,幫咱們加載類、運行。但卻沒法知足我個性化的需求。命令行雖然麻煩,倒是更加本質。windows
至少從這一點上看,java的命令行編譯運行仍是很是重要的。oracle
我查閱了很多網上資料,發現資料雖多,卻並不齊全,也不是太清晰。因而整理以下,但願對初涉java命令行編譯運行的筒子有些幫助吧!eclipse
許多初學者編譯運行時候的Exception的發生,下面的方法都能解決了~若是你遇到什麼問題,仔細看看下面先~說不定有所幫助噢。函數
java的運行機制的基本概念:優化
源文件 也就是咱們熟知的.java文件。
類文件 .class文件是編譯器由.java文件編譯而成。衆所周知,Java的跨平臺性在於Java虛擬機(JVM)這一層對硬件的隔離,而.class文件能夠理解爲JVM中的執行文件(本身的理解,可能不太準確)。裏面存儲的是java字節碼,java bytecode 是基於棧的(stack based)(關於字節碼和JVM更詳細的官方解釋能夠參照 The Java Virtual Machine Specification ,若是嫌那本書太厚,另外再推薦一本 Programming for the Java Virtual Machine)。
編譯 Java的編譯通常是指從源文件(.java文件)到類文件(.class文件)的轉化過程。在JDK命令行中是 javac 命令(java compiler的縮寫~跟C語言木關係的~)
運行 在JVM中執行.class文件。是 java 命令。
CLASSPATH 環境變量,存儲着編譯某文件或運行某類時,所要搜索的目錄。 好比:在Hello.java中有使用到一個第三方包ThirdPart.jar中的類,那麼必須在classpath中添加相應的路徑,讓編譯器能找到它。(注意~把ThirdParty.jar放在當前的工做目錄下,沒有告訴環境變量也是不行的~編譯器只認環境變量的!)一樣的道理,在運行某類文件時,有涉及到第三方jar包的也必須添加到CLASSPATH中。通常的,有三種方式修改環境變量。
1.在javac 或者java命令中,使用 -classpath 選項,後面跟着須要的目錄地址。顯然,這種方法只能在當前語句範圍內生效。
2.直接命令行修改CLASSPATH或者PATH # PATH=$JAVA_HOME/bin:/home/username/bin
#export PATH
不過這種方法只能在這次運行中生效。
3.永久生效的方法是修改配置文件。在 /etc/profile 或者 /etc/profile.d 或者其餘,不一樣操做系統發行版地點不一樣。在文件中加上CLASSPATH=......(相應路徑),重啓電腦便可(也可一執行source命令,那樣不用重啓就已經生效啦~# source /etc/profile.d 其實 . 跟source是同樣的效果噢~ #. /etc/profile.d )
PATH環境變量 跟CLASSPATH 相似,只不過它不是用來尋找類的,而是用來尋找java相關執行文件的。能夠經過 java -version 命令來查看本身是否已經設置好了PATH(若是顯示了詳細java信息,則已經設置好了,沒有的話,還須要找到java的安裝位置,從新設置)
環境變量的具體相關信息,參照doc PATH and CLASSPATH 和 Setting the class path。
jar包
java裏用package的概念避免重複命名的問題。有點像C++的namespace。同一個包裏的類是能夠直接使用的。不一樣包的話,則須要在.java文件頭部import進對應的package。初學者寫的helloworld程序固然是不用注意到包的問題,但當工程愈來愈大,重複命名的可能性增大,咱們就必須依靠package的概念來更好的管理咱們的代碼了。
同時,爲了方便管理、傳輸,jar包出現了。
jar包實際上是用zip壓縮的文件包。咱們能夠打包本身的package,方便複用,到哪果真,也能夠直接引用文件夾(此時注意,必須引用文件夾的根目錄,好比文件定義爲package mypackage.foo , 那個必須將myapackage這個文件夾連同內部的foo文件一塊兒放在相應的路徑上)
製做jar壓縮包和解壓縮包的命令以下:
jar -cvf foo.jar foo其中最後一個參數爲須要壓縮的文件包。-cvf幾個選項中,f必須放在最後,f後面緊跟的必須是output的文件名。v表示輸出詳細信息(verbose)
對應的解壓縮命令爲:
jar -xvf foo.jar
注意其中有個可選的mainifest文件,在META-INF/MANIFEST.MF路徑上。
咱們能夠在manifest.mf文件中加入以下語句
Main-Class: myPackage.MyClass指定MyClass類爲具備main()入口的主類。再利用以下語句,就能夠值執行對應的程序了
java -jar foo.jar
命令
javac命令:編譯源文件
-classpath 初學者必須掌握的options ,後接類中使用到的第三方類(形式能夠是jar或者zip或者直接就是文件包)的目錄。linux下,多個目錄用冒號 : 分隔。
值得注意的是,-classpath中的內容是會覆蓋掉環境變量classpath中的內容的~
-cp 是 -classpath的縮寫
-d 制定生成的.class文件存放的目錄。
-o 此選項告訴javac優化由內聯的static、final以及privite成員函數所產生的碼。
-verbose 此選項告知Java顯示出有關被編譯的源文件和任何被調用類庫的信息。好比 -verbose:class 能看到各類類加載的信息。 -verbose:gc是garbage collection的信息。
還有許多option平時用的很少(話說我也其實只是剛會用,並不熟練直接在命令行環境下的調試編譯 = =),須要用的時候直接翻閱 man javac 好了。
java 命令:加載運行類文件
-classpath 跟javac中的-classpath一樣的道理。
-cp 也就是 -classpath的縮寫啦。
-jar 執行在jar包上定義的主類的程序
一個.java文件的編譯、運行示例以下:
# javac -classpath ./:/home/username/bin/ThirdParty.jar Hello.java
#java -classpath ./:/home/username/bin/ThirdParty.jar Hello
另外,對於帶有package信息的java文件,執行以下:
$ 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,彈出的窗口的左側,有Java Build Path這一選項卡。
這裏主要是對其餘工程包、第三方jar包的路徑引入,也有對project中源文件路徑的設置。
2.在run的下拉菜單中(就是那個綠色的Run開始按鈕),選擇Run Configuration.
在每一個運行的程序中,都有main、argument、JRE、classpath、source、environment、common這幾個選項卡。
其中argument裏能夠設置java命令行運行時的參數。也就試main(String[] args)中的args。
classpath裏能夠設置system classloader加載類時的查找目錄。(關於類的加載,能夠參照另幾篇文章 classloader 三原則 和java 類加載器淺析 )
雷區:
在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!
在運行本身的程序時,遇到了這個問題。查找了不少資料,最後發現原來是路徑問題!原來的路徑中,一個老版本的.class文件是在優先的位置上,因而每次invoke一個新寫的method時,就出現這個錯誤 = =。
若是還有問題,你們能夠多交流啊~