Class.getResource和ClassLoader.getResource的區別分析

Class.getResource(String path)
path不以'/'開頭時,默認是今後類所在的包下取資源;path以'/'開頭時,則是從項目的ClassPath根下獲取資源。在這裏'/'表示ClassPath
JDK設置這樣的規則,是很好理解的,path不以'/'開頭時,咱們就能獲取與當前類所在的路徑相同的資源文件,而以'/'開頭時能夠獲取ClassPath根下任意路徑的資源。
以下所示的例子:java

運行結果爲:
file:/D:/work_space/java/bin/net/swiftlet/
file:/D:/work_space/java/bin/swift

Class.getClassLoader().getResource(String path)
path不能以'/'開頭時,path是指類加載器的加載範圍,在資源加載的過程當中,使用的逐級向上委託的形式加載的,'/'表示Boot ClassLoader中的加載範圍,由於這個類加載器是C++實現的,因此加載範圍爲null。以下所示:jvm

運行結果爲:
file:/D:/work_space/java/bin/
null
從上面能夠看出:
class.getResource("/") == class.getClassLoader().getResource("")
其實,Class.getResource和ClassLoader.getResource本質上是同樣的,都是使用ClassLoader.getResource加載資源的。下面請看一下jdk的Class源碼:this

從上面就能夠看纔出來:Class.getResource和ClassLoader.getResource本質上是同樣的,而且Class.getResource的實現時考慮類加載器爲null的狀況,直接使用更方便。至於爲何Class.getResource(String path)中path能夠'/'開頭,是由於在name = resolveName(name);進行了處理:spa

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
private String resolveName ( String name )
     {
         if ( name == null )
         {
             return name ;
         }
         if ( ! name . startsWith ( "/" ) )
         {
             Class c = this ;
             while ( c . isArray ( ) ) {
                 c = c . getComponentType ( ) ;
             }
             String baseName = c . getName ( ) ;
             int index = baseName . lastIndexOf ( '.' ) ;
             if ( index != - 1 )
             {
                 name = baseName . substring ( 0 , index ) . replace ( '.' , '/' )
                     + "/" + name ;
             }
         } else
         { //若是是以"/"開頭,則去掉
             name = name . substring ( 1 ) ;
         }
         return name ;
     }
Class.getResource和Class.getResourceAsStream在使用時,路徑選擇上是同樣的。
ClassLoader.getResource和ClassLoader.getResourceAsStream在使用時,路徑選擇上也是同樣的。
總結:在獲取資源路徑時推薦使用class.getResource,尤爲是class.getResource("/")的狀況,不然若是用class().getClassLoader().getResource("")還要考慮class().getClassLoader()可能爲空的狀況(若當前類被jvm初始根引導加載器加載時,返回值就爲null),直接使用 class.getResource("/")更方便


相關文章
相關標籤/搜索