java和javac編譯運行java程式

來源:互聯網
上載者:User

標籤:javac

目錄

  • 目錄
  • 前言
  • 編譯命令介紹
    • javac
    • java
  • 代碼編譯與運行
    • java類發現規則
    • 分離class和java檔案
  • 參考連結

前言

給自己定了一個月學習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目錄下增加兩個測試檔案,內容如下:

  1. src/jvm/CompileClass.java
package jvm;public class CompileClass {    public static void main(String[] args) {        TestClass1 mTestClass1 = new TestClass1();        mTestClass1.sayHello();    }}
  1. 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程式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.