1. getClass().getResource()
第一步,
getClass().getResource(path)
是有一個路徑引數的,這個路徑會先被轉換成"類所在的包名稱+path",舉個例子,當呼叫com.test.A.class.getResource(“config.properties”)
時,最終這個path會被轉換為"com\test\config.properties"。
第二步,便會呼叫類的類載入器物件的getResource()方法,繼續上面的例子,也就是等於:
com.test.A.class.getClassLoader().getResource("com\test\config.properties")
(為了方便A類的類載入其物件簡稱cl)。
第三步,分析
cl.getResource()
發現,此方法會返回cl的"第一條匹配到記錄的載入路徑+path"的URL物件。舉個例子,cl類載入器的載入路徑是"\home\aaa"和"\home\bbb",而config.properties在\home\bbb下面,那麼cl.getResource("com\test\config.properties")
返回的URL就是"\home\bbb\com\test\config.properties",注意,這個尋找的過程也是符合雙親委託機制的。如果父類的載入路徑中存在匹配項,那麼返回的便是父類中的匹配路徑。(此方法中核心部分是要被子類來覆蓋的,所以此處說的是URLClassLoader中的實現)
2. ClssLoader.getSystemResource()
ClssLoader.getSystemResource(path)
更簡單,它等價getSystemClassLoader().getResource(path)
,銜接上面的第三步。
3. 總結
也就是說,不管是類物件的getResource()還是類載入器的getSystemResouce(),都是走的類載入器的getResource(),類載入器會搜尋自己的載入路徑來匹配尋找項。而最常用的類載入器就是AppClassLoader,又因為APPClassLoader的載入路徑是classpath,所以網上文章一般都會說getClass().getResouce()是返回classpath,這是不夠準確的。