getResource(String name)用法及源码分析

Project获取资源需要一个启点,加载资源的动作是由ClassLoader来完成的。
Class对象和当前线程对象可以找到当前加载资源的ClassLoader,
通过ClassLoader的getResource(String name)方法及其它衍生出来的方法可以找到Application的启点及获取相关资源
private void display() {
path=this.getClass().getResource("/loadresource").getPath();
System.out.println(path);
path=this.getClass().getResource("/loadresource/bp.txt").getPath();
System.out.println(path);
path=this.getClass().getResource("/").getPath();
System.out.println(path);
URL url=this.getClass().getResource(“loadresource/bp.txt”);
System.out.println(“Is Null:”+(url==null));

    path=GetResouceTest.class.getClassLoader().getResource("").getPath();
    System.out.println(path);
    path=GetResouceTest.class.getClassLoader().getResource("loadresource/bp.txt").getPath();
    System.out.println(path);
    url=GetResouceTest.class.getClassLoader().getResource("/loadresource/bp.txt");
    System.out.println("Is Null:"+(url==null));
    
    
    path=Thread.currentThread().getContextClassLoader().getResource("").getPath();
    System.out.println(path);
    path=Thread.currentThread().getContextClassLoader().getResource("loadresource/bp.txt").getPath();
    System.out.println(path);
    url=Thread.currentThread().getContextClassLoader().getResource("loadresource/bp.txt");
    System.out.println("Is Null:"+(url==null));
    url=Thread.currentThread().getContextClassLoader().getResource("/loadresource/bp.txt");
    System.out.println("Is Null:"+(url==null));
    
}

output
/E:/java/workspace/test/bin/loadresource
/E:/java/workspace/test/bin/loadresource/bp.txt
/E:/java/workspace/test/bin/
Is Null:true
/E:/java/workspace/test/bin/
/E:/java/workspace/test/bin/loadresource/bp.txt
Is Null:true
/E:/java/workspace/test/bin/
/E:/java/workspace/test/bin/loadresource/bp.txt
Is Null:false
Is Null:true

Conclusion:
java.lang.Class的URL getResource(String name)时可以使用参数:
(1)"/":代表项目根目录,也就是ClassPath的root

(2)以"/"开头的包路径

java.lang.ClassLoader的URL getResource(String name)时使用参数:
(1)"":代表项目根目录,也就是ClassPath的root
(2)不以"/"开头的包路径

源码解析:

java.lang.Class
/**
* Finds a resource with a given name. The rules for searching resources
* associated with a given class are implemented by the defining
* {@linkplain ClassLoader class loader} of the class. This method
* delegates to this object’s class loader. If this object was loaded by
* the bootstrap class loader, the method delegates to {@link
* ClassLoader#getSystemResource}.
*
*

Before delegation, an absolute resource name is constructed from the
* given resource name using this algorithm:
*
*


    *
    *
  • If the {@code name} begins with a {@code ‘/’}
    * (’\u002f’), then the absolute name of the resource is the
    * portion of the {@code name} following the {@code ‘/’}.
    *
    *
  • Otherwise, the absolute name is of the following form:
    *
    *

    * {@code modified_package_name/name}
    *

    *
    *

    Where the {@code modified_package_name} is the package name of this
    * object with {@code ‘/’} substituted for {@code ‘.’}
    * (’\u002e’).
    *
    *


*
* @param name name of the desired resource
* @return A {@link java.net.URL} object or {@code null} if no
* resource with this name is found
* @since JDK1.1
*/
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);
}

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

扫描二维码关注公众号,回复: 11084800 查看本文章

从源码看:
(1)java.lang.Class的getResource(String name)方法调用了ClassLoader的getResource(String name)方法;

(2)java.lang.Class的resolveName(String name)方法去掉了name中的第一个字符“/”,

java.lang.Classloader的getResource(String name)的参数name首字母没有“/”

Extension section:

如果路径中有空格及中文在某些场景会出来问题。

可以尝试在getResource(Sting name).toURL()来解决。

发布了14 篇原创文章 · 获赞 0 · 访问量 923

猜你喜欢

转载自blog.csdn.net/qq_35201262/article/details/105578512
今日推荐