一文理解class.getClassLoader().getResourceAsStream(file)和class.getResourceAsStream(file)区别

https://blog.csdn.net/feeltouch/article/details/83796764

class是指当前类的class对象,getClassLoader()是获取当前的类加载器,什么是类加载器?
简单点说,就是用来加载java类的,类加载器负责把class文件加载进内存中,
并创建一个java.lang.Class类的一个实例,也就是class对象,并且每个类的类加载器都不相同。
getResourceAsStream(path)是用来获取资源的,而类加载器默认是从classPath下获取资源的,因为这下面有class文件吗,
所以这段代码总的意思是通过类加载器在classPath目录下获取资源.并且是以流的形式。

我们知道在Java中所有的类都是通过加载器加载到虚拟机中的,而且类加载器之间存在父子关系,
就是子知道父,父不知道子,这样不同的子加载的类型之间是无法访问的(虽然它们都被放在方法区中),
所以在这里通过当前类的加载器来加载资源也就是保证是和类类型同一个加载器加载的。 

不同点
1. class.getClassLoader().getResourceAsStream(String name)

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

eg:

InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("gamvanclub.cfg.xml");
2. class.getResourceAsStream(String name)

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

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

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

eg:

//从classpath下的config相对路径中读取config.ini"
mypackage.Hello.class.getResourceAsStream("/config/config.ini");
 如果name不是以"/"开头,那么绝对路径是package名"."换成“/”以后再加name。

eg:

//com.abc.App就是/com/abc/App/name 或者写作 : ../../name(以class所在路径为基准,文件相对于该类的路径)
Java类加载过程
3个步骤:

1.加载,加载类的二进制文件。

2.链接:

  (1)验证,验证字节码的结构是否正确

  (2)准备,给静态成员分配空间并赋予默认值(注意这里:静态变量的第一次赋值是在类加载的时候就进行了,
与后面初始化的时候的自定义赋值不是同一过程,也就是静态成员在初始化的时候可能已被赋值二次了)

  (3)解析,将符号引用变为直接引用

3初始化,为静态成员赋予自己给定的初值

类的实例化的顺序:

(1)静态成员、方法与静态代码块的初始化与执行

(2)普通成员、方法与普通代码块的初始化与执行

(3)构造函数的执行(父类的构造函数先执行)
posted @ 2020-04-23 16:22  种树人  阅读(373)  评论(0编辑  收藏  举报