ClassLoader类加载器原理解析

ClassLoader类加载器原理解析

首先的了解下我们的类加载器 - 类加载器就是把我们的.class文件加载到JVM中生成对应的Class对象

1.BootStrapClassLoader - 这个类是我们JVM的类(OpenJDK)C++写的,它负责加载我们JRE lib下面的核心类库如rt.jar - 也就是我们的lang和util等等包下的类(String。。)

2. ExtClassLoader  - 这个类是负责加载我们ext包下面的类

3. AppClassLoader - 负责加载我们APP(一般是classpath)下面的类

4. CustomerClassLoader - 程序员自定义的类加载器

当一个类加载器去加载一个Class文件的时候默认情况下并不会自己去加载而是由父类加载器去加载,当父类加载器发现类不是自己加载的范畴就会让子类去加载 -  这个机制就是网上的双亲委派 - 个人觉得叫父类委托,哪来的双亲?

上面的机制就会保证一个Class文件只会被一个类加载器加载(同时也保证在系统中一个Class对象只会存在一份),而且只会被加载一次,因为当ClassLoader加载一个class文件后会在本地缓存(下面源码解析会说到)一个Class的引用,当再次加载这个Class文件的时候会去本地引用找,找到直接return就不会在加载。

如果同一个Class被2个ClassLoader加载(这种情况下只会发生在程序员自定义的类加载)他们的类型是不同的,相互转化的时候会报错

A a = ClassLoaderA.load

A b = ClassLoaderB.load

a = b 会报错

考虑一个问题自己写一个String类会不会被加载?

1.如果自己定义个String类而且包名是java.lang这个String类是不会被加载的

-通过双亲委派机制,这个类会被BootStrapClassLoader加载,但是它会去先加载我们核心类库(JRE lib包下的rt.jar里面的java.lang.String),由于缓存,它不会再加载我们的这个java.lang.String

2.如果随意包名就会被加载。

类加载器加载原理(源码分析)

ClassLoader - 这是我们的顶级父类,Ext 和App两个classloader都是它的子类

1.ClassLoader里面有一个ClassLoader的一个属性来维护parent关系的

2.loadClass(String name) - 通过类名来

3.this.findLoadedClass(name) -首先去本地缓存(里面调用的一个native方法,说明缓存是在JVM中的)去找,找到就返回,找不到继续

4.if (this.parent !=null) {

c =this.parent.loadClass(name, false);

}else {

c =this.findBootstrapClassOrNull(name);

} - 这就是双亲委派机制,- 这里也是个递归调用。

5.if (c ==null) {

c =this.findClass(name);

} - 如果父类返回null(没有加载这个class)就调用自己的findClass方法加载

你可能感兴趣的:(ClassLoader类加载器原理解析)