this.getClass().getClassLoader().getResource("");

        <1> 調用對象的getClass()方法是獲得對象當前的類類型,這部分數據存在方法區中。
        <2>類類型上調用getClassLoader()方法是得到當前類型的類加載器。
        我們知道在Java中所有的類都是通過類加載器加載到虛擬機中的,而且類加載器之間存在父子關係,就是子知道父,父不知道子,這樣不同的子加載的類型之間是無法訪問的(雖然它們都被放在方法區中),所以在這裏通過當前類的加載器來加載資源也就是保證是和類類型同一個加載器加載的。最後調用了類加載器的getResourceAsStream()方法來加載資源。返回讀取到的資源的輸入流。getResource()獲取其URL。
     經常希望通過ClassName.class.getClassLoader().getResourceAsStream(““)來取得properties文件.通常:ClassName.class.getClassLoader().getResourceAsStream(““)取得的是WEB-INF的下級目錄,比如ClassName.class.getClassLoader().getResourceAsStream(“db.properties“).在Tomcat中,可以通過增加”../”來取得上層目錄,即WEB-INF目錄,這樣就可以把properties放在WEB-INF中統一管理。但是WLS不識別”../”。   另外一種土辦法,就是不返回classLoader,直接ClassName.class.getResourceAsStream()。然後通過多個”../”(小於6個)來返回相應的上級目錄。當然,如果類擴展了HttpServlet,可以通過getServletContext().getRealPath("/")來取得Web部署目錄的絕對路徑。 
     getClass():取得當前對象所屬的Class對象   
     getClassLoader():取得該Class對象的類裝載器
      裝載類的過程非常簡單:查找類所在位置,並將找到的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()“),這樣一來就不會有問題。儘量不要使用提供的封裝類來獲取他的加載器。因爲這樣會報空指針我們應該使用我們自定義的類來獲取它的類加載器。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章