2016-02-21 93 views
3

在我的理解中,所有java類都被動態加載到內存中,即當第一次看到一個CLASS符號時,它將其內容加載到內存中。正確定義java動態類加載

在java中,我們常說,我們正在做以下時,JVM加載類動態 :

(1)

Class aClass = classLoader.loadClass("com.stackoverflow.MyClass"); 

但是,從我之前所說的,對我來說,似乎總是一樣的東西。 我的意思是不需要更多的步驟來加載一個類,使用片段(1),比第一次碰到一個CLASS符號時加載類時所需的步驟。

我錯了嗎? 一直以來他們是兩個不同的概念嗎? 謝謝

回答

4

嘛,他們不是完全相同相同,但總體而言,你說得對,classLoader.loadClass("com.stackoverflow.MyClass")基本上給出了相同的效果,只是指com.stackoverflow.MyClass類裏面。

classLoader.loadClassClass.forName等的主要動力是,他們讓你加載類是通過硬編碼字符串命名。例如,類名可能出現在配置文件中。 (The Spring framework,例如,做盡可能多的這是任何人所能想。)

其次,這些方法也提出在該類無法加載的情況下,更可操作的例外。例如,SLF4J提供了其他庫可以編譯的單個API JAR文件,但提供了幾種不同的實現JAR文件,最終應用程序可以使用它們進行部署(一個委託給Log4j,一個委託給java.util.logging.Logger等)。在運行時,SLF4J會嘗試通過動態加載org.slf4j.impl.StaticLoggerBinder來查找已部署的實現,但如果找不到它,它只會打印警告(並且默認爲不執行操作)而不是炸燬。如果SLF4J API JAR文件中的類靜態取決於org.slf4j.impl.StaticLoggerBinder類,則此方法無效。

2

我認爲classLoader.loadClass("com.stackoverflow.MyClass")確實是告訴編譯器明確加載指定的類爲當前classLoader。在正常情況下,類已經在執行程序的類路徑中,你的假設是正確的,它已經默認加載了。

但是,可能會出現需要從其他來源(如網絡或二進制流)中讀取類的情況。在這種情況下,默認加載行爲可能不會讀取這些類,loadClass()將指示編譯器明確加載它們。

欲瞭解更多詳細信息,您可以參考ClassLoader javadoc