標籤:javac
目錄
- 目錄
- 前言
- 編譯命令介紹
- 代碼編譯與運行
- 參考連結
前言
給自己定了一個月學習JVM虛擬機器的計劃,不管有沒有卵用,學點新東西總是好的。
但是在學習過程中,我想在命令列測試一些JVM參數的時候,發現自己脫離了IDE,竟然無法直接編譯java程式!!
我的原則不能抱怨太多,像個Loser,不會的就花時間補回來。
下面,主要是總結一些如何在命令列中編譯java程式。主要是想記錄總結一下java的類發現原則。
編譯命令介紹
其實,java編譯過程主要使用了javac和java兩個命令。這裡先介紹一下這兩個命令的使用方法。
javac
javac用於將java檔案編譯成byte-code class檔案。使用方法如下:
javac [ options ] [ sourcefiles ] [ classes ] [ @argfiles ]
其中options有幾個關鍵參數:
- -d:指定編譯成的class檔案的存放位置。預設情況下,編譯產生的class檔案和源java檔案在同一目錄下。
- -classpath(-cp):用於搜尋編譯所需要的class檔案,指出編譯所用到的class檔案的位置。
java
java用於執行程式,格式如下:
java [options] classfile
其中,options一般需要指定-classpath參數,用於指定要執行的檔案所在的位置以及需要用到的類的路徑。
代碼編譯與運行
這裡介紹一個帶package的測試案例。以前大家在學習javac編譯的時候,都是在預設包下進行的編譯,一般不會出問題,但是遇到帶package的類就不一樣了。
樣本目錄結構如下:
其中,src是預設的package目錄。我們在src/jvm目錄下增加兩個測試檔案,內容如下:
- src/jvm/CompileClass.java
package jvm;public class CompileClass { public static void main(String[] args) { TestClass1 mTestClass1 = new TestClass1(); mTestClass1.sayHello(); }}
- src/jvm/TestClass1.java
package jvm;public class TestClass1 { public void sayHello() { System.out.println("Hello World!"); } public static void main(String[] args) { TestClass1 mTestClass1 = new TestClass1(); mTestClass1->sayHello(); }}
這時,如果直接在src/jvm目錄下,用javac編譯CompileClass,報錯如下:
我想平時大家寫完這麼簡單的代碼,用Ecplise點一下run按鈕是不可能遇到這種問題的。那之所以會遇到這個問題,就是由於Ecplise這種編譯器替我們掩蓋了java是有類發現規則的。
java類發現規則
要想成功的編譯和執行java檔案,是需要有classpath和包名的共同配合。
我們先嘗試禁用一下classpath,禁用的方法是在運行javac的時候,指定
-classpath ""。
在src/jvm目錄下,我們禁用classpath,編譯TestClass1.java:
javac -classpath "" TestClass1.java
大家執行之後,發現是可以編譯通過的(至於能否執行大家先不要在意)。
但是,同樣在src/jvm目錄下,我們禁用classpath去編譯CompileClass.java,是無法編譯通過的,編譯錯誤和之前是一樣的。之所以ComplieClass.java無法編譯通過,是因為ComplieClass.java的源碼中調用了TestClass1這個類,而禁用掉classpath之後,javac無法找到TestClass1了。由此,我們可以總結出如下規律:
當你需要編譯(或執行)的類A引用了其他的類如B時,編譯器需要在-classpath指定的目錄下去找B。
當類B中也指定了package時,那B的路徑path=classpath + “/” + package(將所有的”.”轉換為”/”)。
因此,在src/jvm目錄下,為了能讓ComplieClass.java在編譯時間能夠找到TestClass1這個類,我們需要這樣設定classpath:
javac -classpath ".." CompileClass.java
執行的時候,命令如下:
java -classpath ".." jvm.CompileClass
分離.class和.java檔案
在瞭解了java類發現規則之後,我們應該再去最佳化一下我們的編譯方法。
參考Eclipse,它在java項目的根目錄下,分別建立了一個src目錄和一個bin目錄。其中:
- src目錄:存放所有的.java檔案。
- bin目錄:存放所有的編譯出來的.class檔案。
我們可以很輕鬆的通過-d參數指定目錄實現該功能。並且,當我們這麼做的時候,bin目錄產生的.class檔案都保持了src目錄的相應結構,我們就不用再去費心考慮classpath尋找類的問題了。
樣本過程如所示:
參考連結
[1] Mastering the JAVA CLASSPATH
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
java和javac編譯運行java程式