2009-12-17 134 views
32

我有一些代碼,調用..getClass()。getClassLoader()爲null,爲什麼?

x = getClass().getClassLoader(); 

這雖然返回null。

當我從Eclipse啓動相同的代碼,但在命令行中,它返回一個類加載器。

我可以破解的代碼做到這一點...

if (getClass().getClassLoader() == null) 
{ 
x = ClassLoader.getSystemClassLoader().getSystemResourceAsStream(loadedPropFileName); 
} 

都被編譯並用相同的JVM上運行。 (我99.99%肯定)。

任何人有任何想法,爲什麼第一個將爲類加載器返回null?

編輯:

我的問題是不「任何人有任何想法,爲什麼當通過Eclipse和命令行加載時一個類加載器啓動時的同一類將返回null」

感謝Bootstap加載器必須在Eclipse中加載類的建議。我不知道爲什麼會發生這種情況。

回答

30

引述API doc

一些實施方案可使用null 表示引導類加載器。 如果此類是由引導類加載器加載的 ,則此方法將在此類 實現中返回null。

+3

是的,但如果執行方式相同,爲什麼命令行和Eclipse中的行爲不同。我認爲這是OP真正要求的...... – 2009-12-17 12:02:37

+1

如果他想知道與他所要求的不同的東西,爲什麼他不問他真正想知道的內容? – Bombe 2009-12-17 12:22:50

3

有一件事是肯定的,Eclipse比從命令行運行時有更深更復雜的classloader設置。如果你看到一個類的類加載器在一個類中出現差異,那麼這是一個很可能的原因。

我不是究竟Eclipse是做知識淵博,但我認爲這很可能是你的類是由引導類加載器加載在Eclipse中運行時,但Eclipse正在試圖使它看起來這樣。

一旦應用程序被引導,啓動類加載器就是靜態的,並且以後除非Eclipse重寫了實現,否則不能向其中添加jar或類,在這種情況下,還有另一種可能的解釋。

0

我有同樣的問題。但解決它使用: -

<ClassName>.class.getClass().getResource(urlString); 

希望這會幫助別人......

7

這是如何工作的。每當JVM嘗試加載任何類時,都會在以下條件下進行檢查。

如果從Bootstrap ClassPath加載Class,即; jdk \ jre \ lib \ rt.jar,將調用BootStrap ClassLoader。

如果從擴展類路徑加載類,即; jdk \ jre \ lib \ ext * .jar,擴展類加載器將被調用。

如果Class是從Application ClassPath加載的,即:如環境變量中指定的那樣,調用Application ClassLoader。

因爲Bootstrap ClassLoader沒有在java中實現,所以它不是在c或C++中實現的,所以沒有引用它就是爲什麼它返回null。但擴展和應用程序類加載器是用java編寫的,因此您將獲得[email protected][email protected]的引用。因此,如果你做了這樣的事情,你可以使用System.out.println(String.class.getClassLoader()),因爲這個類已經被BootStrap ClassLoader調用了,另一方面,如果你這樣做對於Ext或App類路徑中的類,您將分別得到 $ ExtClassLoader @ someHexValue和[email protected]

0

「如果此類由引導類加載器加載,則此方法將在此類實現中返回null。」 - JavaDoc at getClassLoader()

爲了安全起見,null類加載器是爲系統類保留的,只能在Class.forName(String name,boolean initialize,ClassLoader loader)時使用。如果一個類有一個空ClassLoader,那麼大多數安全檢查都不會被執行。

相關問題