2016-09-16 39 views
0

我想了解爲什麼JVM在沒有出現需要時決定加載某些類。請看下面的例子代碼:爲什麼Java ClassLoader正在加載這個類

public class Foo { 
    public void foo() { 
    } 

    static class Bar { 
    } 

    public Bar bar() { 
     return new Bar(); 
    } 
} 

當調用new Foo().foo()Bar不是由類加載器加載,因爲它是沒有必要的。但是,如果我們改變的例子有bar返回一個子類的實例:

public class Foo {  
    public void foo() { 
    } 

    static class Bar { 
    } 

    static class BigBar extends Bar { 
    } 

    public Bar bar() { 
     return new BigBar(); 
    } 
} 

調用new Foo().foo()導致類加載器加載兩種即使他們都不是必要的BarBigBar類。爲什麼?

除了這個特定的場景,有沒有一種方法可以瞭解爲什麼JVM決定它需要加載一個類,一般來說?

+0

你的問題是神祕的。如果您有JDK8,則將使用JDK8。您不能同時使用2個JDK。 –

+0

你是否用'-target 1.7'編譯了代碼並測試了它在7版JRE上的運行方式?這將是一種更直接的方式來看它如何處理,而不是猜測類加載器在做什麼。 – Kayaman

+1

@JoshStone哪些代碼?哪些類? 「一些代碼嘗試從Java 8加載一些類」並沒有太多的工作。 – Kayaman

回答

1

這裏是Internals of Java Class Loading

每當一個新的JVM是由輸入java MyMainClass開始一個良好的閱讀中, 「引導類加載器」是負責加載關鍵的Java類 像java.lang.Object中和其他運行時代碼首先進入內存。 運行時類包裝在JRE \ lib \ rt.jar文件中。我們 在Java 文檔中找不到引導程序類加載器的詳細信息,因爲這是本機實現。對於相同的 原因,引導程序類加載器的行爲在不同JVM之間也會有差異 。

log(java.lang.String.class.getClassLoader()); 

接下來是Java擴展類加載器:

在一個相關的說明,如果我們試圖得到一個核心Java運行時類的類加載器 ,這樣我們會得到空。我們可以在java.ext.dirs屬性給出的路徑中存儲擴展 庫,這些庫提供超出核心Java 運行時代碼的功能。 ExtClassLoader負責加載保存在 java.ext.dirs路徑中的所有.jar文件。開發人員可以將他或她自己的應用程序 .jar文件或任何可能需要添加到 類路徑的庫添加到此擴展目錄,以便它們將由 加載擴展類加載器。

來自開發人員 透視圖的第三個也是最重要的類加載器是AppClassLoader。應用程序類加載器是 ,負責加載與java.class.path系統屬性對應的路徑 中保留的所有類。

+0

我對一般的類加載很熟悉。我需要學習的是觸發一個類在這個確切場景中被加載的內容,因爲它並不明顯。 –

0

很好地解釋http://javarevisited.blogspot.in/2012/07/when-class-loading-initialization-java-example.html

當類在Java中被加載 類加載是由在Java中的類加載器,其可以被實現爲一旦急切裝載一個類作爲另一個類引用完成它或者延遲加載的類,直至需要類初始化。如果Class在實際使用之前被加載,它可以在被初始化之前坐在裏面。我相信這可能會從JVM到JVM有所不同。雖然JLS保證當需要靜態初始化時會加載一個類。 當在Java 中初始化類時1)使用new()關鍵字或使用class.forName()使用反射來創建類的實例,該類可能會拋出Java中的ClassNotFoundException。 2)調用Class的靜態方法。 3)分配一個類的靜態字段。 4)使用不是常量變量的類的靜態字段。 5)如果Class是一個頂級類,並且執行了一個在詞類中嵌套的assert語句。

+0

你讀過這個問題了嗎?該類在被引用或使用之前被加載。根據你發佈的鏈接,不應該加載課程。 –

相關問題