文章目錄
- 聯編選項
- 非標準選項
- 編譯簡單程式
- 編譯多個源檔案
- 指定使用者類路徑
- 將源檔案和類檔案分開
- 聯編程式樣本
結構
javac [ options ] [ sourcefiles ] [ @files ]
參數可按任意次序排列。
-
options
-
命令列選項。
-
sourcefiles
-
一個或多個要編譯的源檔案(例如 MyClass.java)。
-
@files
-
一個或多個對源檔案進行列表的檔案。
說明
javac 工具讀取用 Java 程式設計語言編寫的類和介面定義,並將它們編譯成位元組碼類檔案。
有兩種方法可將原始碼檔案名稱傳遞給 javac:
- 如果源檔案數量少,在命令列上列出檔案名稱即可。
- 如果源檔案數量多,則將源檔案名稱列在一個檔案中,名稱間用空格或斷行符號行來進行分隔。然後在 javac 命令列中使用該列表檔案名稱,檔案名稱前冠以 @ 字元。
原始碼檔案名稱必須含有 .java 尾碼,類檔案名稱必須含有 .class 尾碼,源檔案和類檔案都必須有識別該類的根名。例如,名為 MyClass 的類將寫在名為 MyClass.java的源檔案中,並被編譯為位元組碼類檔案 MyClass.class。
內部類定義產生附加的類檔案。這些類檔案的名稱將內部類和外部類的名稱結合在一起,例如 MyClass$MyInnerClass.class。
應當將源檔案安排在反映其包樹結構的分類樹中。例如,如果將所有的源檔案放在 /workspace 中,那麼 com.mysoft.mypack.MyClass 的代碼應該在 /workspace/com/mysoft/mypack/MyClass.java 中。
預設情況下,編譯器將每個類檔案與其源檔案放在同一目錄中。可用 -d 選項(請參閱後面的選項)指定其它目標目錄。
尋找類型
當編譯源檔案時,編譯器常常需要它還沒有識別出的類型的有關資訊。對於源檔案中使用、擴充或實現的每個類或介面,編譯器都需要其類型資訊。這包括在源檔案中沒有明確提及、但通過繼承提供資訊的類和介面。
例如,當擴充 java.applet.Applet 時還要用到 Applet 的祖先類:java.awt.Panel 、 java.awt.Container、 java.awt.Component 和 java.awt.Object。
當編譯器需要類型資訊時,它將尋找定義類型的源檔案或類檔案。編譯器先在自舉類及擴充類中尋找,然後在使用者類路徑中尋找。使用者類路徑通過兩種途徑來定義:通過設定 CLASSPATH 環境變數或使用 -classpath 命令列選項。(有關詳細資料,請參閱設定類路徑)。如果使用 -sourcepath 選項,則編譯器在 sourcepath 指定的路徑中尋找源檔案;否則,編譯器將在使用者類路徑中尋找類檔案和源檔案。可用-bootclasspath 和 -extdirs 選項來指定不同的自舉類或擴充類;參閱下面的聯編選項。
成功的類型搜尋可能產生類檔案、源檔案或兩者兼有。以下是 javac 對各種情形所進行的處理:
注意: javac 可以隱式編譯一些沒有在命令列中提及的源檔案。用 -verbose 選項可跟蹤自動編譯。
檔案清單
為縮短或簡化 javac 命令,可以指定一個或多個每行含有一個檔案名稱的檔案。在命令列中,採用 '@' 字元加上檔案名稱的方法將它指定為檔案清單。當 javac 遇到以 `@' 字元開頭的參數時,它對那個檔案中所含檔案名稱的操作跟對命令列中檔案名稱的操作是一樣的。這使得 Windows 命令列長度不再受限制。
例如,可以在名為 sourcefiles 的檔案中列出所有源檔案的名稱。該檔案可能形如:
MyClass1.java MyClass2.java MyClass3.java
然後可用下列命令運行編譯器:
C:> javac @sourcefiles
選項
編譯器有一批標準選項,目前的開發環境支援這些標準選項,將來的版本也將支援它。還有一批附加的非標準選項是目前的虛擬機器實現所特有的,將來可能要有變化。非標準選項以 -X 打頭。
標準選項
-
-classpath 類路徑
-
設定使用者類路徑,它將覆蓋 CLASSPATH 環境變數中的使用者類路徑。若既未指定 CLASSPATH 又未指定 -classpath,則使用者類路徑由目前的目錄構成。有關詳細資料,請參閱設定類路徑。
若未指定 -sourcepath 選項,則將在使用者類路徑中尋找類檔案和源檔案。
-
-d 目錄
-
設定類檔案的目標目錄。如果某個類是一個包的組成部分,則 javac 將把該類檔案放入反映包名的子目錄中,必要時建立目錄。例如,如果指定 -d c:/myclasses 並且該類名叫
com.mypackage.MyClass,那麼類檔案就叫作 c:/myclasses/com/mypackage/MyClass.class。
若未指定 -d 選項,則 javac 將把類檔案放到與源檔案相同的目錄中。
注意: -d 選項指定的目錄不會被自動添加到使用者類路徑中。
-
-deprecation
-
顯示每種不鼓勵使用的成員或類的使用或覆蓋的說明。沒有給出 -deprecation 選項的話, javac 將顯示這類源檔案的名稱:這些源檔案使用或覆蓋不鼓勵使用的成員或類。
-
-encoding
-
設定源檔案編碼名稱,例如
EUCJIS/SJIS。若未指定 -encoding 選項,則使用平台預設的轉換器。
-
-g
-
產生所有的調試資訊,包括局部變數。預設情況下,只產生行號和源檔案資訊。
-
-g:none
-
不產生任何調試資訊。
-
-g:{關鍵字列表}
-
只產生某些類型的調試資訊,這些類型由逗號分隔的關鍵字列表所指定。有效關鍵字有:
-
source
-
源檔案調試資訊
-
lines
-
行號調試資訊
-
vars
-
局部變數調試資訊
-
-nowarn
-
禁用警告資訊。
-
-O
-
最佳化代碼以縮短執行時間。使用 -O 選項可能使編譯速度下降、產生更大的類檔案並使程式難以調試。
在 JDK 1.2 以前的版本中,javac 的 -g 選項和 -O 選項不能一起使用。在 JDK 1.2 中,可以將 -g 和 -O 選項結合起來,但可能會得到意想不到的結果,如丟失變數或重新置放代碼或丟失代碼。-O 選項不再自動開啟 -depend 或關閉 -g 選項。同樣, -O 選項也不再允許進行跨類內嵌。
-
-sourcepath 源路徑
-
指定用以尋找類或介面定義的原始碼路徑。與使用者類路徑一樣,源路徑項用分號 (;) 進行分隔,它們可以是目錄、JAR 歸檔檔案或 ZIP 歸檔檔案。如果使用包,那麼目錄或歸檔檔案中的本地路徑名必須反映包名。
注意:通過類路徑尋找的類,如果找到了其源檔案,則可能會自動被重新編譯。
-
-verbose
-
冗長輸出。它包括了每個所載入的類和每個所編譯的源檔案的有關資訊。
聯編選項
預設情況下,類是根據與 javac 一起發行的 JDK 自舉類和擴充類來編譯。但 javac 也支援聯編,在聯編中,類是根據其它 Java平台實現的自舉類和擴充類來進行編譯的。聯編時, -bootclasspath 和 -extdirs 的使用很重要;請參閱下面的聯編程式樣本。
-
-target 版本
-
產生將在指定版本的虛擬機器上啟動並執行類檔案。預設情況下產生與 1.1 和 1.2 版本的虛擬機器都相容的類檔案。JDK 1.2 中的 javac 所支援的版本有:
-
1.1
-
保證所產生的類檔案與 1.1 和 1.2 版的虛擬機器相容。這是預設狀態。
-
1.2
-
產生的類檔案可在 1.2 版的虛擬機器上運行,但不能在 1.1 版的虛擬機器上運行。
-
-bootclasspath 自舉類路徑
-
根據指定的自舉類集進行聯編。和使用者類路徑一樣,自舉類路徑項用分號 (;) 進行分隔,它們可以是目錄、JAR 歸檔檔案或 ZIP 歸檔檔案。
-
-extdirs 目錄
-
根據指定的擴充目錄進行聯編。目錄是以分號分隔的目錄列表。在指定目錄的每個 JAR 歸檔檔案中尋找類檔案。
非標準選項
-
-X
-
顯示非標準選項的有關資訊並退出。
-
-Xdepend
-
遞迴地搜尋所有可獲得的類,以尋找要重編譯的最新源檔案。該選項將更可靠地尋找需要編譯的類,但會使編譯進程的速度大為減慢。
-
-Xstdout
-
將編譯器資訊送到
System.out 中。預設情況下,編譯器資訊送到 System.err 中。
-
-Xverbosepath
-
說明如何搜尋路徑和標準擴充以尋找源檔案和類檔案。
-
-J選項
-
將選項傳給 javac 調用的 java 啟動器。例如, -J-Xms48m 將啟動記憶體設為 48 MB。雖然它不以 -X 開頭,但它並不是 javac 的‘標準選項’。用 -J 將選項傳給執行用 Java 編寫的應用程式的虛擬機器是一種公用約定。
注意: CLASSPATH 、 -classpath 、 -bootclasspath 和 -extdirs 並 不 指定用於運行 javac 的類。如此濫用編譯器的實現通常沒有任何意義而且總是很危險的。如果確實需要這樣做,可用 -J 選項將選項傳給基本的 java 啟動器。
程式樣本
編譯簡單程式
一個源檔案 Hello.java ,它定義了一個名叫 greetings.Hello 的類。greetings 目錄是源檔案和類檔案兩者的包目錄,且它不是目前的目錄。這讓我們可以使用預設的使用者類路徑。它也使我們沒必要用 -d 選項指定單獨的目標目錄。
C:> dirgreetings/C:> dir greetingsHello.javaC:> cat greetings/Hello.javapackage greetings;public class Hello { public static void main(String[] args) { for (int i=0; i < args.length; i++) { System.out.println("Hello " + args[i]); } }}C:> javac greetings/Hello.javaC:> dir greetingsHello.class Hello.javaC:> java greetings.Hello World Universe EveryoneHello WorldHello UniverseHello Everyone
編譯多個源檔案
該樣本編譯 greetings 包中的所有源檔案。
C:> dirgreetings/C:> dir greetingsAloha.java GutenTag.java Hello.java Hi.javaC:> javac greetings/*.javaC:> dir greetingsAloha.class GutenTag.class Hello.class Hi.classAloha.java GutenTag.java Hello.java Hi.java
指定使用者類路徑
對前面樣本中的某個源檔案變更後,重新編譯它:
C:> cd/examplesC:> javac greetings/Hi.java
由於 greetings.Hi 引用了 greetings 包中其它的類,編譯器需要找到這些其它的類。上面的樣本能運行是因為預設的使用者類路徑剛好是含有包目錄的目錄。但是,假設我們想重新編譯該檔案並且不關心我們在哪個目錄中的話, 我們需要將 /examples 添加到使用者類路徑中。可以通過設定 CLASSPATH 達到此目的,但這裡我們將使用 -classpath 選項來完成。
C:>javac -classpath /examples /examples/greetings/Hi.java
如果再次將 greetings.Hi 改為使用標題公用程式,該公用程式也需要通過使用者類路徑來進行訪問:
C:>javac -classpath /examples:/lib/Banners.jar / /examples/greetings/Hi.java
要執行 greetings 中的類,需要訪問 greetings 和它所使用的類。
C:>java -classpath /examples:/lib/Banners.jar greetings.Hi
將源檔案和類檔案分開
將源檔案和類檔案置於不同的目錄下經常是很有意義的,特別是在大型的項目中。我們用 -d 選項來指明單獨的類檔案目標位置。由於源檔案不在使用者類路徑中,所以用 -sourcepath 選項來協助編譯器尋找它們。
C:> dirclasses/ lib/ src/C:> dir srcfarewells/C:> dir src/farewellsBase.java GoodBye.javaC:> dir libBanners.jarC:> dir classesC:> javac -sourcepath src -classpath classes:lib/Banners.jar / src/farewells/GoodBye.java -d classesC:> dir classesfarewells/C:> dir classes/farewellsBase.class GoodBye.class
注意:編譯器也編譯了 src/farewells/Base.java,雖然我們沒有在命令列中指定它。要跟蹤自動編譯,可使用 -verbose 選項。
聯編程式樣本
這裡我們用 JDK 1.2 的 javac 來編譯將在 1.1 版的虛擬機器上啟動並執行代碼。
C:> javac -target 1.1 -bootclasspath jdk1.1.7/lib/classes.zip / -extdirs "" OldCode.java
-target 1.1 選項可確保產生的類檔案與 1.1 版的虛擬機器相容。在 JDK1.2 中, 預設情況下 javac 編譯產生的檔案是與 1.1 版的虛擬機器相容的,因此並非嚴格地需要該選項。然而,由於別的編譯器可能採用其它的預設設定,所以提供這一選項將不失為是個好習慣。
JDK 1.2 javac 在預設狀態下也將根據 1.2 版的自舉類來進行編譯,因此我們需要告訴 javac 讓它根據 JDK 1.1 自舉類來進行編譯。可用 -bootclasspath 和 -extdirs 選項來達到此目的。不這樣做的話,可能會使編譯器根據 1.2 版的 API 來進行編譯。由於 1.1 版的虛擬機器上可能沒有該 1.2 版的 API,因此運行時將出錯。
文章來原:http://www.iplab.cs.tsukuba.ac.jp/~liuxj/jdk1.2/zh/docs/tooldocs/win32/javac.html