Class.getResource和ClassLoader.getResource区别与分析
来源:互联网 发布:mean it 编辑:程序博客网 时间:2024/05/22 12:22
零、 前言
在一个获取文件路径的代码内容上发现单元测试出现NullPointer, 但是这段代码却在服务器正常运行了两年多, 借此机会想认真探索下这两个方法的区别。
一、 区别
区别从代码输出结果来看比较清晰,
文件结构图:
以下为在多个场景下使用方式的代码:
package com.wenniuwuren.test;/** * 获取文件路径 * Created by wenniuwuren on 15/8/14. */public class GetResourceTest { public static void main(String[] args) { // 带 “/” 的其实就是返回根目录 System.out.println("GetResourceTest.class.getResource(\"/\") -----> " + GetResourceTest.class.getResource("/")); System.out.println("GetResourceTest.class.getResource(\"/DD.DD\") -----> " + GetResourceTest.class.getResource("/DD.DD")); // ************************************************* // 返回当前路径 System.out.println("GetResourceTest.class.getResource(\"\") -----> " + GetResourceTest.class.getResource("")); System.out.println("GetResourceTest.class.getResource(\"AA.AA\") -----> " + GetResourceTest.class.getResource("AA.AA")); System.out.println("GetResourceTest.class.getResource(\"subtest/BB.BB\") -----> " + GetResourceTest.class.getResource("subtest/BB.BB")); System.out.println("GetResourceTest.class.getResource(\"../CC.CC\") -----> " + GetResourceTest.class.getResource("../CC.CC")); // 查找classloader root。 用 getClassLoader 最容易出问题, 因为是根据类加载器来的, 类加载器多种多样可能在不同环境下产生不同结果 GetResourceTest getResourceTest = new GetResourceTest(); System.out.println("getResourceTest.getClass().getClassLoader().getResource(\"\") -----> " + getResourceTest.getClass().getClassLoader().getResource("")); System.out.println("getResourceTest.getClass().getClassLoader().getResource(\"/\") -----> " + getResourceTest.getClass().getClassLoader().getResource("/")); /** * 从输出结果来看总结上述: Class.class.getResource("/") == Class.getClass().getClassLoader().getResource("") */ // 这是一种可以避免在不同Web容器下获取路径异常的方法 System.out.println("GetResourceTest.class.getProtectionDomain().getCodeSource().getLocation().getPath() -----> " + GetResourceTest.class.getProtectionDomain().getCodeSource().getLocation().getPath()); }}
二、 从源码角度分析
分析前先看个 Java 类加载的架构图, 有助于下文理解:
1. Class.getResource
算法基本为: 搜索策略为此类关联的类加载器实现的, 即这个方法委托给这个对象的类加载器,如果对象是被 Bootstrap 类加载器加载的, 则进入 ClassLoader.getSystemResource() 方法, 这个方法先找系统级别的类加载器(这个加载器是一般应用启动的类加载器), 如果找不到则使用虚拟机内置的类加载器。
如果传的参数是“/”则返回根路径, 传的是具体文件名就返回文件绝对路径。
public java.net.URL getResource(String name) { name = resolveName(name); ClassLoader cl = getClassLoader0(); if (cl==null) { // A system class. return ClassLoader.getSystemResource(name); } return cl.getResource(name); }
2. ClassLoader.getResource
会先从父加载器去找资源, 如果父加载器为 null 则从虚拟机内置加载器去查找(这步何上面最后一步相同), 如果还没有, 则去findResource() [可以重写这个方法自己实现个类加载器去寻找资源]去找。
public URL getResource(String name) { URL url; if (parent != null) { url = parent.getResource(name); } else { url = getBootstrapResource(name); } if (url == null) { url = findResource(name); } return url; }
3 0
- Class.getResource和ClassLoader.getResource区别与分析
- java Class.getResource和ClassLoader.getResource的区别分析
- Class.getResource和ClassLoader.getResource的区别分析
- Class.getResource和ClassLoader.getResource的区别分析
- Class.getResource和ClassLoader.getResource的区别分析
- Class.getResource和ClassLoader.getResource的区别分析
- Class.getResource和ClassLoader.getResource的区别分析及用法
- Class.getResource和ClassLoader.getResource的区别分析
- Class#getResource与ClassLoader#getResource分析
- Class.getResource与ClassLoader.getResource()区别
- Class.getResource与ClassLoader.getResource()区别
- Class.getResource()与ClassLoader.getResource()区别
- Class.getResource() 和 ClassLoader.getResource() 的区别
- Class.getResource和ClassLoader.getResource 的区别
- Class.getResource和ClassLoader.getResource
- Class.getResource和ClassLoader.getResource
- Class.getResource和ClassLoader.getResource
- Class.getResource()、ClassLoader.getResource()、ClassLoader.getSystemResource()区别
- 助力开发团队
- OpenGL-vs2012-glfw-glew 测试环境搭建
- 新的征程
- 8.27总结
- 领英的kafka安装和配置
- Class.getResource和ClassLoader.getResource区别与分析
- 例题3.13 周期 LA3026
- ZOJ1745 解题报告
- IOS动画Core Animation详解
- URAL 2052 Physical Education(数位dp)
- 在 Parallels Desktop 中,全屏模式使用 Win7,唤醒时黑屏
- Centos6.5安装使用NFS
- 总结的一些css3的一些东西,放个地方吧
- 使用EmguCv计算包围物体的最小圆与最小可旋转矩形和不可选择矩形