在使用Class.getResourceAsStream 时,资源路径有两种方式,一种以 / 开头,则这样的路径是指定绝对路径,如果不以 / 开头,则路径是相对与这个class所在的包的。我们看一下Class.java是如何实现的:
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
26
27
28
29
30
31
32
33
|
public
InputStream getResourceAsStream(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if
(cl==
null
) {
// A system class.
return
ClassLoader.getSystemResourceAsStream(name);
}
return
cl.getResourceAsStream(name);
}
/**
* Add a package name prefix if the name is not absolute Remove leading "/"
* if name is absolute
*/
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.getResourceAsStream最终调用是ClassLoader.getResourceAsStream
只是在这之前对参数进行了调整。如果参数已/开头,则去除/,否则把当前类的包名加在参数的前面。想一想你就明白了。
在使用ClassLoader.getResourceAsStream时,路径直接使用相对于classpath的绝对路径,并且不能已 / 开头。
下面的三个语句,实际结果是一样的:
com.guojje.A.class.getResourceAsStream("B.class")
= com.guojje.A.class.getResourceAsStream("/com/guojje/B.class")
= ClassLoader.getResourceAsStream("com/guojje/B.class")
对于ClassLoader.getResourceAsStream,如果已/开头,则返回一直为null.
本文转自 anranran 51CTO博客,原文链接:http://blog.51cto.com/guojuanjun/964145