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
;
}
|