2013-05-06 43 views
6

我對Java編譯器有一些疑問。我對Java編譯器有一些疑問

我目前的目錄是這樣的。

├── Hoge.java 
├── Sample.class 
├── Sample.java 
├── pattern01 
│   └── com 
│    └── cat 
│     └── Hoge.class 
└── pattern02 
    └── com 
     └── cat 
      └── Hoge.class 

----- ----- Sample.java

import com.cat.Hoge; 

public class Sample { 

    public static void main(String[] args) { 
     System.out.println("hello!"); 
     Hoge h = new Hoge(); 
     h.call(); 
    } 
} 

----- ----- pattern01

package com.cat; 

public class Hoge { 

    public void call() { 
     System.out.println("com.cat"); 
     System.out.println("pattern01"); 
    } 
} 

----- pattern02 -----

package com.cat; 

public class Hoge { 

    public void call() { 
     System.out.println("com.cat"); 
     System.out.println("pattern02"); 
    } 
} 

我編譯Sample.java是這樣的。

$ javac -cp pattern01 Sample.java 

而且我這樣執行。

$ java -cp .:pattern01 Sample 
hello! 
com.cat 
pattern01 

$ java -cp .:pattern02 Sample 
hello! 
com.cat 
pattern02 

pattern01和pattern02都正常結束。

但我用pattern01編譯。爲什麼程序通常以pattern02結束?

編譯器檢查什麼?編譯器是否只檢查類名?

回答

8

類在運行時解析。您在類路徑中使用Hoge類的一個版本編譯客戶端類(Sample),並使用另一個版本的類運行它。由於類仍然兼容(相同的包,相同的名稱,相同的方法簽名),一切都很順利。

這就是允許使用給定版本的庫(或JDK)編譯類,但仍然使用同一庫(或JDK)的另一版本運行它。如果這是不可能的,那麼構建可重用的庫將是一場噩夢,因爲每個庫都必須針對每個版本的JDK和每個依賴庫的每個版本進行編譯。