forName().getResourceAsStream和forName().getClassLoader().getResourceAsStream方法的区别及总结(API文档分析)

问题描述:

在载入一个properties文件的时候,由于我的粗心写了一行易错代码 - -,
InputStream is = Class.forName("utils._03DruidUtils").getResourceAsStream("druid.properties");
结果直接给我报出一个空指针异常NullPointerException
forName().getResourceAsStream和forName().getClassLoader().getResourceAsStream方法的区别及总结(API文档分析)_第1张图片


我仔细分析了下代码,一般空指针异常是读取文件没有读到,所以我就注意到了这一行代码

InputStream is = Class.forName("utils._03DruidUtils").getResourceAsStream("druid.properties");

原因分析:

PS:如果您觉得分析太麻烦,可以看总结~

于是我就查阅了API文档,发现这个getResourceAsStream这个方法是有解释的
forName().getResourceAsStream和forName().getClassLoader().getResourceAsStream方法的区别及总结(API文档分析)_第2张图片

大概意思已经解释在图中,
1.如果用类来调用getResourceAsStream,是需要一个绝对路径的
2.如果已经载入加载器,那需要的并不是绝对路径

解决方案:

有了上面的理解我们可以知道

InputStream is = Class.forName("utils._03DruidUtils").getResourceAsStream("druid.properties");

错误原因在于用类来调用getResourceAsStream,但却用了相对路径。所以如果要修改,只需要用文件的绝对路径,从根目录写起就可以了(我的文件是放在src下的,所以根目录在src)
在这里插入图片描述
可以将代码修改为

InputStream is = Class.forName("utils._03DruidUtils").getResourceAsStream("/druid.properties");

上下代码差距只有一个/
此时代码就不会再报空指针异常了
在这里插入图片描述

举一反三:

我们知道的错误原因,那么可以写出另一种代码

InputStream is = Class.forName("utils._03DruidUtils").getClassLoader().getResourceAsStream("druid.properties");
//这里就是因为有了getClassLoader(),将类加载进了内存,所以此时可以不用绝对路径,所以不用/

这样的写法也是正确的

总结:

就算您觉得前面的分析太复杂,我做一个小总结

通过getResourceAsStream加载文件有两种方式(第二种一定放入绝对路径)

  • 第一种:xxx.class.getClassLoader().getResourceAsStream("xxx.properties")
  • 第二种:xxx.class.getResourceAsStream("/xxx.properties") (从根目录开始写出绝对路径)

我推荐用第二种方法,这种方法不仅可以减少代码书写,而且对于xxx.properties文件的放置位置也是可以自己定义的,只要写清楚绝对路径即可。方便多了~

  • 举个栗子:我将properties放到单独文件夹下面统一管理
    forName().getResourceAsStream和forName().getClassLoader().getResourceAsStream方法的区别及总结(API文档分析)_第3张图片
  • 代码修改成utils._03DruidUtils.class.getResourceAsStream("/properties/druid.properties");即可

我按照自己的理解写了一下总结,但是不知道能否讲述清楚,如果有不明白的。欢迎留言与我讨论,我会完善这篇文章的~

你可能感兴趣的:(java学习笔记,java,class,NullPointer,空指针异常)