關getClass().getClassLoader()

InputStream   is   =   getClass().getClassLoader().getResourceAsStream("helloworld.properties");中getClass()和getClassLoader()都是什麼意思呀.
getClass():取得當前對象所屬的Class對象  
getClassLoader():取得該Class對象的類裝載器
類裝載器負責從Java字符文件將字符流讀入內存,並構造Class類對象,在你說的問題哪裏,經過它能夠獲得一個文件的輸入流
getClass :
public final Class getClass()
Returns the runtime class of an object. That Class object is the object that is locked by static synchronized methods of the represented class.
Returns:
the object of type Class that represents the runtime class of the object.java


getClassLoader
public ClassLoader getClassLoader()
Returns the class loader for the class. Some implementations may use null to represent the bootstrap class loader. This method will return null in such implementations if this class was loaded by the bootstrap class loader.
If a security manager is present, and the caller´s class loader is not null and the caller´s class loader is not the same as or an ancestor of the class loader for the class whose class loader is requested, then this method calls the security manager´s checkPermission method with a RuntimePermission("getClassLoader") permission to ensure it´s ok to access the class loader for the class.bootstrap

If this object represents a primitive type or void, null is returned.測試

Returns:
the class loader that loaded the class or interface represented by this object.
Throws:
SecurityException - if a security manager exists and its checkPermission method denies access to the class loader for the class.
See Also:
ClassLoader, SecurityManager.checkPermission(java.security.Permission), RuntimePermission

Class.getClassLoader()的一個小陷阱:)
昨天個人code總在Integer.class.getClassLoader().getResource("*********");這一句拋出空指針異常,定位爲getClassLoader()返回null,查了一下jdk的文檔,原來這裏還有一個陷阱:
jdk中關於getClassLoader()的描述:
/**
     * Returns the class loader for the class. Some implementations may use
     * null to represent the bootstrap class loader. This method will return
     * null in such implementations if this class was loaded by the bootstrap
     * class loader.
     *
     * <p> If a security manager is present, and the caller's class loader is
     * not null and the caller's class loader is not the same as or an ancestor of
     * the class loader for the class whose class loader is requested, then
     * this method calls the security manager's <code>checkPermission</code>
     * method with a <code>RuntimePermission("getClassLoader")</code>
     * permission to ensure it's ok to access the class loader for the class.
     *
     * <p>If this object
     * represents a primitive type or void, null is returned.
.....this

上面的英文能夠用下面的話來理解:spa

裝載類的過程很是簡單:查找類所在位置,並將找到的Java類的字節碼裝入內存,生成對應的Class對象。Java的類裝載器專門用來實現這樣的過程,JVM並不止有一個類裝載器,事實上,若是你願意的話,你可讓JVM擁有無數個類裝載器,固然這除了測試JVM外,我想不出還有其餘的用途。你應該已經發現到了這樣一個問題,類裝載器自身也是一個類,它也須要被裝載到內存中來,那麼這些類裝載器由誰來裝載呢,總得有個根吧?沒錯,確實存在這樣的根,它就是神龍見首不見尾的Bootstrap ClassLoader. 爲何說它神龍見首不見尾呢,由於你根本沒法在Java代碼中抓住哪怕是它的一點點的尾巴,儘管你能時時刻刻體會到它的存在,由於java的運行環境所須要的全部類庫,都由它來裝載,而它自己是C++寫的程序,能夠獨立運行,能夠說是JVM的運行起點,偉大吧。在Bootstrap完成它的任務後,會生成一個AppClassLoader(實際上以前系統還會使用擴展類裝載器ExtClassLoader,它用於裝載Java運行環境擴展包中的類),這個類裝載器纔是咱們常常使用的,能夠調用ClassLoader.getSystemClassLoader() 來得到,咱們假定程序中沒有使用類裝載器相關操做設定或者自定義新的類裝載器,那麼咱們編寫的全部java類統統會由它來裝載,值得尊敬吧。AppClassLoader查找類的區域就是耳熟能詳的Classpath,也是初學者必須跨過的門檻,有沒有靈光一閃的感受,咱們按照它的類查找範圍給它取名爲類路徑類裝載器。仍是先前假定的狀況,當Java中出現新的類,AppClassLoader首先在類傳遞給它的父類類裝載器,也就是Extion ClassLoader,詢問它是否可以裝載該類,若是能,那AppClassLoader就不幹這活了,一樣Extion ClassLoader在裝載時,也會先問問它的父類裝載器。咱們能夠看出類裝載器其實是一個樹狀的結構圖,每一個類裝載器有本身的父親,類裝載器在裝載類時,老是先讓本身的父類裝載器裝載(多麼尊敬長輩),若是父類裝載器沒法裝載該類時,本身就會動手裝載,若是它也裝載不了,那麼對不起,它會大喊一聲:Exception,class not found。有必要提一句,當由直接使用類路徑裝載器裝載類失敗拋出的是NoClassDefFoundException異常。若是使用自定義的類裝載器loadClass方法或者ClassLoader的findSystemClass方法裝載類,若是你不去刻意改變,那麼拋出的是ClassNotFoundException。指針

這裏jdk告訴咱們:若是一個類是經過bootstrap 載入的,那咱們經過這個類去得到classloader的話,有些jdk的實現是會返回一個null的,好比說我用 new Object().getClass().getClassLoader()的話,會返回一個null,這樣的話上面的代碼就會出現NullPointer異常.因此保險起見咱們最好仍是使用咱們本身寫的類來獲取classloader("this.getClass().getClassLoader()「),這樣一來就不會有問題。code

相關文章
相關標籤/搜索