为何ClassLoader.getResource()返回null,与Class.getResource()结果不同?
为什么
ClassLoader.getResource("/java/lang/String.class")返回null? 核心差异:路径处理逻辑不同
Class.getResource()和ClassLoader.getResource()的核心区别在于对路径参数的处理规则,这直接导致了你的代码中第三个调用返回null。
1. Class.getResource(String path)的工作机制
- 当路径以
/开头时:方法会自动去掉开头的斜杠,然后委托当前类的类加载器执行getResource(),等效于:class.getClassLoader().getResource(path.substring(1)); - 当路径不以
/开头时:方法会将当前类的包名(把.替换为/)与路径拼接,再委托类加载器查找,比如Prova.class.getResource("test.txt")会变成com/xxx/Prova/test.txt(假设Prova在com.xxx包下)。
你的代码中前两个调用:
Prova.class.getResource("/java/lang/String.class"); String.class.getResource("/java/lang/String.class");
因为路径以/开头,内部会转换为java/lang/String.class再交给类加载器查找,而这个路径在JRE的rt.jar中存在,所以能返回正确的URL。
2. ClassLoader.getResource(String path)的工作机制
- 类加载器的getResource方法直接以类路径根目录为起点查找资源,路径参数不能以
/开头,也不会对路径做任何自动转换。 - 如果传入带
/的路径,类加载器会尝试查找类路径下名为/java/lang/String.class的资源——但这个路径并不存在(正确的路径是java/lang/String.class),所以返回null。
对应你的代码:
Prova.class.getClassLoader().getResource("/java/lang/String.class");
传入的路径带斜杠,类加载器找不到对应资源,因此返回null。
Web服务器环境的类似问题
在Web应用中,类加载器结构更复杂(通常包含应用类加载器、容器类加载器等),这类null问题更常见:
- 误用带斜杠的路径调用
ClassLoader.getResource(),同样会因为路径格式错误返回null; - 不同类加载器的查找范围不同:比如容器类加载器无法访问WEB-INF/classes下的应用私有资源,应用类加载器也可能无法访问容器级别的资源,若调用了错误的类加载器,也会导致资源查找失败。
内容的提问来源于stack exchange,提问作者luca.vercelli
相关产品推荐
相关产品推荐

