本文部分转自:http://xixinfei.iteye.com/blog/1256291

this.getClass().getClassLoader().getResource("template"); 
  首先,调用对象的getClass()方法是获得对象当前的类类型,这部分数据存在方法区中,而后在类类型上调用getClassLoader()方法是得到当前类型的类加载器,我们知道在Java中所有的类都是通过加载器加载到虚拟机中的,而且类加载器之间存在父子关系,就是子知道父,父不知道子,这样不同的子加载的类型之间是无法访问的(虽然它们都被放在方法区中),所以在这里通过当前类的加载器来加载资源也就是保证是和类类型同一个加载器加载的。 
最后调用了类加载器的getResourceAsStream()方法来加载资源。

====================================

JAVA运行时,首先会在指定的类路径下(classpath路径下)搜索JAVA编译后的字节码文件(class文件),然后通过类加载器加载到虚拟机中。 DBConn.class.getClassLoader().getResourceAsStream("database.properties")
1、DBConn.class得到表示DBConn类的Class对象,请参照JDK中对Class的说明http://wenku.baidu.com/view/1fa5e8ebe009581b6bd9ebe1.html
2、通过Class的getClassLoader方法取得加载DBConn类的类加载器对象ClassLoader。
3、调用ClassLoader的getResourceAsStream方法从类加载路径取得文件的输入流(会通过当前的ClassLoader的findResource方法查找指定文件),请参照:http://download.oracle.com/javase/1.5.0/docs/api/java/lang/ClassLoader.html#getResourceAsStream%28java.lang.String%29


====================================

下面的JdbcUtils.class后面少了个()吗?应该是都可以

Properties prop = new Properties();
   prop.load(JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties"));
   String driver = prop.getProperty("driver");
   Class.forName(driver);

====================================

  1. 关于ClassName.class.getClassLoader的几点说明.
  2. 经常希望通过ClassName.class.getClassLoader().getResourceAsStream(““)来取得properties文件.通常:ClassName.class.getClassLoader().getResourceAsStream(““)取得的是WEB-INF的下级目录,比如ClassName.class.getClassLoader().getResourceAsStream(“db.properties“).在Tomcat中,可以通过增加”../”来取得上层目录,即WEB-INF目录,这样就可以把properties放在WEB-INF中统一管理。但是WLS不识别”../”。
  3. 另外一种土办法,就是不返回classLoader,直接ClassName.class.getResourceAsStream()。然后通过多个”../”(小于6个)来返回相应的上级目录。
  4. 当然,如果类扩展了HttpServlet,可以通过getServletContext().getRealPath("/")来取得Web部署目录的绝对路径。

====================================

因此,直接调用 this.getClass().getResourceAsStream(String name);获取流,静态化方法中则使用ClassLoader.getSystemResourceAsStream(String name); 。

====================================

在JDK中,getResourceAsStream是这样定义的:查找具有给定名称的资源。查找与给定类相关的资源的规则是通过定义类的 class loader 实现的。 
因为我是用txt文件当作字典,它存在一个叫dict.aspactword的包下,这样一来,编译后的文件会储存在classPath下,而不是在src下,在动态向字典添加词的时候,classPath下的txt字典没有改变,相对在getResourceAsStream的时候,拿到的自然不是最新的字典,由此感叹,在classPath下如果有不需要改变的文件,在读取时用getResourceAsStream可以保持系统良好的统一性和可移植性,但是在需要改变它们的时候,一定注意修改的路径是classPath下的文件,否则就直接用文件系统的位置来维护你所需要的文件吧

=====================================================================================================

常见的有以下两种获取资源文件的方法:

方法一: App.class.getClassLoader().getResourceAsStream(String name)

Returns an input stream for reading the specified resource.

The search order is described in the documentation for getResource(String).

默认从classpath中找文件(文件放在resources目录下),name不能带“/”,否则会抛空指针

方法二: App.class.getResourceAsStream(String name)

查找资源通过给定名称,查询资源的规则与给定的类的class load来实现,这个方法由类的loader来执行,如果这个类由bootstrap加载,那么方法由ClassLoader.getSystemResourceAsStream代理执行。

代理之前,绝对的资源名称通过传入的name参数以下算法进行构造:

如果name以"/"开头,那么绝对路径是/后边跟的名字

如果name不是以"/"开头,那么绝对路径是package名"."换成“/”以后再加name,例如:com.abc.App就是/com/abc/App/name 或者写作 : ../../name(以class所在路径为基准,文件相对于该类的路径)

总结:(表述不清将就着看吧笨人有笨法 o_O ...)

  (1)Xxx.class.getClassLoader().getResourceAsStream(String name);

    文件放在resources目录下,name写作:"xxx.properties"

    

  (2)Xxx.class.getResourceAsStream(String name);

    文件放在任意package下

      a.如果同级目录name写作:"xxx.properties";

      b.如果在另一package下name写作"../xxpackage/xxx.properties"

=====================================================================================================

另,可参考另一篇文章:Class.getResource和ClassLoader.getResource的区别分析

在Java中获取资源的时候,经常用到Class.getResource和ClassLoader.getResource,本文给大家说一下这两者方法在获取资源文件的路径差异。
Class.getResource(String path)
path不以'/'开头时,默认是从此类所在的包下取资源;path以'/'开头时,则是从项目的ClassPath根下获取资源。在这里'/'表示ClassPath
JDK设置这样的规则,是很好理解的,path不以'/'开头时,我们就能获取与当前类所在的路径相同的资源文件,而以'/'开头时可以获取ClassPath根下任意路径的资源。
如下所示的例子:

 
1
2
3
4
5
6
7
8
public class Test
{
    public static void main(String[] args)
    {
        System.out.println(Test.class.getResource(""));
        System.out.println(Test.class.getResource("/"));
    }
}

运行结果为:
file:/D:/work_space/java/bin/net/swiftlet/
file:/D:/work_space/java/bin/

Class.getClassLoader().getResource(String path)
path不能以'/'开头时,path是指类加载器的加载范围,在资源加载的过程中,使用的逐级向上委托的形式加载的,'/'表示Boot ClassLoader中的加载范围,因为这个类加载器是C++实现的,所以加载范围为null。如下所示:

 
1
2
3
4
5
6
7
8
public class Test
{
    public static void main(String[] args)
    {
        System.out.println(Test.class.getClassLoader().getResource(""));
        System.out.println(Test.class.getClassLoader().getResource("/"));
    }
}

运行结果为:
file:/D:/work_space/java/bin/
null
从上面可以看出:
class.getResource("/") == class.getClassLoader().getResource("")
其实,Class.getResource和ClassLoader.getResource本质上是一样的,都是使用ClassLoader.getResource加载资源的。下面请看一下jdk的Class源码:

 
1
2
3
4
5
6
7
8
9
10
11
  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);
    }

从上面就可以看才出来:Class.getResource和ClassLoader.getResource本质上是一样的。至于为什么Class.getResource(String path)中path可以'/'开头,是因为在name = resolveName(name);进行了处理:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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;
    }

this.class.getClassLoader().getResourceAsStream与this.class.getResourceAsStream 文件地址获取的更多相关文章

  1. this.class.getClassLoader().getResourceAsStream与this.class.getResourceAsStream

    本文部分转自:http://xixinfei.iteye.com/blog/1256291 this.getClass().getClassLoader().getResource("tem ...

  2. 有关getClassLoader().getResourceAsStream(fileName)、class.getResourceAsStream(fileName)和().getContextClassLoader().getResourceAsStream(fileName)的区别

    一:前言 在自己获取属性时,碰见了XX.class.getResourceAsStream(fileName),自己对这个其实不是很理解,上网查了下资料,又看到了上述的几个,所以就研究了下. 二:内容 ...

  3. 分析Class类和ClassLoader类下的同名方法getResourceAsStream

    在读取本地资源的时候我们经常需要用到输入流,典型的场景就是使用Druid连接池时读取连接池的配置文件.Java为我们提供了读取资源的方法getResourceAsStream(),该方法有三种: Cl ...

  4. getResourceAsStream 地址

    getResourceAsStream ()返回的是inputstream getResource()返回:URL Class.getResource("")    返回的是当前C ...

  5. java中使用相对路径读取文件的写法总结 ,以及getResourceAsStream() (转)

    https://blog.csdn.net/my__sun_/article/details/74450241 读取文件的写法,相对路径 在当前的目录结构中读取test.txt的有四种写法 简单粗暴的 ...

  6. Class.getResourceAsStream和ClassLoader.getResourceAsStream方法

    项目中,有时候要读取当前classpath下的一些配置文件,下面介绍下Class.getResourceAsStream和ClassLoader.getResourceAsStream两种方法以及两者 ...

  7. 【转载】java文件路径问题及getResource和getClassLoader().getResource的区别

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u012572955/article/details/52880520我们经常在java的io操作中读 ...

  8. Spring源码分析——资源访问利器Resource之实现类分析

    今天来分析Spring的资源接口Resource的各个实现类.关于它的接口和抽象类,参见上一篇博文——Spring源码分析——资源访问利器Resource之接口和抽象类分析 一.文件系统资源 File ...

  9. maven下读取资源文件的问题(转)

    原文链接:http://shenchao.me/2016/04/20/maven%E4%B8%8B%E8%AF%BB%E5%8F%96%E8%B5%84%E6%BA%90%E6%96%87%E4%BB ...

随机推荐

  1. 【转】簡單講講 USB Human Interface Device

    原地址http://213style.blogspot.com/2013/09/usb-human-interface-device.html 恩,發本文的原因是看到了以前畢業的朋友在旁邊的對話框問了 ...

  2. Java设计模式——合成/聚合复用原则

    一.什么是合成/聚合复用原则? 合成/聚合复用原则是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分:新的对象通过向这些对象的委派达到复用已有功能的目的. 简述为:要尽量使用合成/聚合,尽 ...

  3. redis异常和注意点

    目录: 1. 修改配置不起作用 2.Connection reset by peer: socket write error 3. redis-cli 查看中文乱码 1. 修改配置不起效果 我们修改了 ...

  4. 01_hello world

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. Delphi 中的颜色常量及效果图

    颜色名称   颜色效果   Hex HTML clBlack   $000000 #000000 clMaroon   $000080 #800000 clGreen   $008000 #00800 ...

  6. E_FAIL (0x80004005) MachineWrap

    下载VirtualBox-4.3.12-93733-Win.exe,下载地址:http://download.virtualbox.org/virtualbox/4.3.12/

  7. Pronunciation Guide for 25 Common Fruits

    Pronunciation Guide for 25 Common Fruits Share Tweet Share Tagged With: Vocabulary Words Know how to ...

  8. tar 打包当前目录下文件但不包括该录

    今天想打包一些文件,但是不想把该目录打包进去 比如我想把test目录下文件打个包,安装正常的命令来 tar zcf test.tar.gz test 这样肯定会把test目录也打进去,解压后肯定是te ...

  9. RabbitMQ系列教程之七:RabbitMQ的 C# 客户端 API 的简介(转载)

    RabbitMQ系列教程之七:RabbitMQ的 C# 客户端 API 的简介 今天这篇博文是我翻译的RabbitMQ的最后一篇文章了,介绍一下RabbitMQ的C#开发的接口.好了,言归正传吧. N ...

  10. Linux创建SSH信任关系

    Linux服务器创建信任关系可以解决远程执行命令.远程传输文件多次手工输入的麻烦.可以实现环境一键打包备份. 测试环境 SuSE 手工创建 假设服务器A与B间要建立信任关系.用户想从服务器A免密码登录 ...