2012-08-11 67 views

回答

1

Java Language Specification, §12.3說(我的重點):

本規範允許實現靈活性的活動聯繫起來時(,而且由於遞歸的,裝載)發生,但語言的語義在一個類或接口被初始化之前被完全驗證和準備,並且在鏈接期間檢測到的錯誤被拋出到程序中的某個點,在該點處程序採取了一些行動,可能需要與所涉及的類或接口相關聯在錯誤中。

例如,一個實現可能會選擇分別解析每個類或接口中的每個符號引用,僅當它被使用時(懶惰或解析晚),或者在正在驗證類時靜態解析它們(靜態解析度)。這意味着解析過程可能會繼續,在一些實現中,類或接口已經初始化之後。

現在,規範說,一個JVM 可以做一系列的事情,但很明顯,任何給定的JVM 做一個特別的事情。 Marko的答案是,「即使在方法開始執行之前,類路徑中的所有類文件都可能被加載」,他是對的,但事實是沒有JVM實際上這樣做。

我相信在Sun JVM中實際發生的事情是儘可能晚地加載。每當一個類被初始化時,那麼它引用的任何類都需要被加載和驗證,但是它們不需要被初始化直到它們自己被實際使用。我明白這不是一個非常詳細或權威的答案。

0

我很確定它發生在編譯時。如果不符合所有要求和依賴關係,您將無法獲得代碼的編譯版本。

在編譯的Jar的情況下,我已經準備了兩個類:

public class Test { 
    public static void main(String[] args) { 
     System.out.println("T1: Hello world"); 
    Test2.greet(); 
    } 
} 

和:

public class Test2 { 
    public static void greet() { 
     System.out.println("T2: Hello world"); 
    } 
} 

運行的出口項目的第一次嘗試:

$ java -jar test.jar 
T1: Hello world 
T2: Hello world 

然後,從我的jar文件中刪除Test2.class,然後再次運行它:

$ java -jar test-mod.jar 
T1: Hello world 
Exception in thread "main" java.lang.NoClassDefFoundError: Test2 
     at Test.main(Test.java:6) 
Caused by: java.lang.ClassNotFoundException: Test2 
     at java.net.URLClassLoader$1.run(Unknown Source) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at java.net.URLClassLoader.findClass(Unknown Source) 
     at java.lang.ClassLoader.loadClass(Unknown Source) 
     at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) 
     at java.lang.ClassLoader.loadClass(Unknown Source) 
     ... 1 more 

T1測試通過,然後出現NoClassDefFoundError異常。所以,回答你的問題:依賴關係將在運行時檢查。

+0

顯然,這不是我的答案!它需要編譯時的所有依賴,但我正在談論運行時。考慮一個Jar文件的「複製版本」。 – MBZ 2012-08-11 10:02:00

+0

好吧,我認爲這聽起來很簡單;)我會很快添加新的答案。 – 2012-08-11 10:08:56

+0

在那裏,我希望它能解決它。 – 2012-08-11 10:20:16

3

恰好當一個.class文件將被加載沒有指定。對於你所知道的,甚至在main方法開始執行之前,類路徑中的所有類文件都可以被加載。

Java指定的唯一事情是當一個類將被初始化爲,這與加載它完全不同。