本文共 4757 字,大约阅读时间需要 15 分钟。
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.txtIs Null:true/E:/java/workspace/test/bin//E:/java/workspace/test/bin/loadresource/bp.txtIs Null:falseIs Null:true
Conclusion:
java.lang.Class<T>的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: * *
* { @code modified_package_name/name} ** *
Where the {
@code modified_package_name} is the package name of this * object with { @code '/'} substituted for { @code '.'} * ('\u002e'). * */** * 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; }
从源码看:
(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()来解决。
转载地址:http://jfuwo.baihongyu.com/