class.getResources与ClassLoader.getResources有不同的访问途径,如果访问方式不对,只会得到null值。
Maven工程目录如下

如上图,编译后,maven会将src下面的代码及资源文件转移至target/classes下面,下文所提及的目录均为转移后的目录。
class.getResources获取资源
package demo;
public class AcquirePath {
//class.getResource(String path)
public static void getPathByClass() {
//path不以"/"开头,则以类所在的当前目录为起点寻址,使用相对位置寻址
//若不使用相对位置寻址,则会返回null
//Maven工程,编译期间会将class及相应的资源文件转移至 classes目录,
//故AcquirePath的当前目录变为
// /F:/test/test/target/classes/demo/
System.out.println(AcquirePath.class.getResource(""));
System.out.println(AcquirePath.class.getResource("."));
//资源文件会同步转移至classes目录下,使用相对位置可获取
System.out.println(AcquirePath.class.getResource("../db/db.properties"));
System.out.println(AcquirePath.class.getResource("../util/util.properties"));
System.out.println(AcquirePath.class.getResource("../root.properties"));
//path以"/"开头,则从classpath路径开始,以绝对位置方式寻址
//若不使用绝对位置寻址,则会返回null
//maven工程中,classpath指class目录
System.out.println(AcquirePath.class.getResource("/"));
System.out.println(AcquirePath.class.getResource("/db/db.properties"));
System.out.println(AcquirePath.class.getResource("/util/util.properties"));
System.out.println(AcquirePath.class.getResource("/root.properties"));
}
}
//打印信息如下
//file:/F:/test/test/target/classes/demo/
//file:/F:/test/test/target/classes/demo/
//file:/F:/test/test/target/classes/db/db.properties
//file:/F:/test/test/target/classes/util/util.properties
//file:/F:/test/test/target/classes/root.properties
//file:/F:/test/test/target/classes/
//file:/F:/test/test/target/classes/db/db.properties
//file:/F:/test/test/target/classes/util/util.properties
//file:/F:/test/test/target/classes/root.properties
从代码中得知,class.getResources(String name)获取资源的途径有两个:
- 相对位置:不以"/"开头,寻址起点为当前类所在的位置
- 绝对位置:以"/"开头,寻址起点为当前工程的classpath路径,maven工程中为target/classes目录
- 不符合上述规则,返回null值
ClassLoader.getResources()获取资源
public static void getPathByClassLoader() {
//ClassLoader.getResource()默认其当前位置即classpath,故无需以"/"开头
//若以"/"开头,反而让编译器找不到路径
System.out.println(AcquirePath.class.getClassLoader().getResource(""));
System.out.println(AcquirePath.class.getClassLoader().getResource("."));
System.out.println(AcquirePath.class.getClassLoader().getResource("/"));
//默认以classpath为寻址起点,故无需以"/"开头,使用绝对路径寻址
System.out.println(AcquirePath.class.getClassLoader().getResource("db/db.properties"));
System.out.println(AcquirePath.class.getClassLoader().getResource("util/util.properties"));
System.out.println(AcquirePath.class.getClassLoader().getResource("root.properties"));
//打印结果如下
//file:/F:/test/test/target/classes/
//file:/F:/test/test/target/classes/
//null
//file:/F:/test/test/target/classes/db/db.properties
//file:/F:/test/test/target/classes/util/util.properties
//file:/F:/test/test/target/classes/root.properties
}
如代码所示,ClassLoader.getResources(String name)规则如下
- 默认以classpath为寻址地点,与类所在目录没必然关系
- 无需以"/"开头,以classpath为起点,进行绝对寻址
- 不符合上述规则,返回null
本文通过实例代码详细解析了Java中class.getResource与ClassLoader.getResource在Maven工程中的资源访问差异。class.getResource以类所在目录为起点,支持相对和绝对路径;而ClassLoader.getResource以类路径为起点,默认进行绝对路径寻址。理解这些区别对于正确读取类路径中的资源文件至关重要。
3903

被折叠的 条评论
为什么被折叠?



