2019-07-11

类加载的双亲机制:

class加载到JVM中有三个步骤

装载:(loading)找到class对应的字节码文件。

连接:(linking)将对应的字节码文件读入到JVM中。   

初始化:(initializing)对class做相应的初始化动作。


1:虚拟机启动时,需要指定一个执行的主类(包含main方法的类),虚拟机会先初始化这类

2:是什么时候要加载类:

1、使用new关键字实例化对象、读取或设置一个类的静态字段(被final修饰、已在编译期把结果放入到常量池的静态字段除外),以及调用一个类的静态方法的时候。

2、使用java.lang.reflect包的方法对类进行反射调用时,如果此类没有初始化,则要触发其初始化。

3、当初始化一个类时,发现其父类还没有进行初始化,则需要先触发其父类的类的初始化

4、当虚拟机启动时,用户需要指定一个要运行的主类(包括main方法的那个类),虚拟机会先初始化这个主类。

5、JDK1.7新增:如果一个java.lang.invoke.MethodHandle实例最后的解析结果是REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个方法的句柄所对应的类没有进行过初始化,则需要先触发其初始化。

类加载器分类

在虚拟机的角度上,只存在两种不同的类加载器:

启动类加载器(Bootstrap ClassLoader),这个类加载器使用C++语言实现,是虚拟机自身的一部分;

其它所有的类加载器,这些类加载器都由Java语言实现,独立于虚拟机外部,并且全部继承自java.lang.ClassLoader,


双亲委派模型是指

如果一个类收到了类加载的请求,不会自己先尝试加载,先找父类加载器去

完成。当顶层启动类加载器表示无法加载这个类的时候,子类才会尝试自己

去加载。当回到最开的发起者加载器还无法加载时,并不会向下找,而是抛

出ClassNotFound异常。(如果类A中引用了类B,Java虚拟机将使用加

载类A的类加载器来加载类B)


BootStrap ClassLoader:主要加载%JRE_HOME%\lib下的rt.jar(顶级加载器C++)

Extention ClassLoader:主要加载目录%JRE_HOME%\lib\ext目录下的jar包和class文件

AppClassLoader:主要加载当前应用下的classpath路径下的类


 例如:当jvm要加载Test.class的时候,

  (1)首先会到自定义加载器中查找,看是否已经加载过,如果已经加载过,则返回字节码。

  (2)如果自定义加载器没有加载过,则询问上一层加载器(即AppClassLoader)是否已经加载过Test.class。

  (3)如果没有加载过,则询问上一层加载器(ExtClassLoader)是否已经加载过。

  (4)如果没有加载过,则继续询问上一层加载(BoopStrap ClassLoader)是否已经加载过。

  (5)如果BoopStrap ClassLoader依然没有加载过,则到自己指定类加载路径下("sun.boot.class.path")查看是否有Test.class字节码,有则返回,没有通

知下一层加载器ExtClassLoader到自己指定的类加载路径下(java.ext.dirs)查看。

  (6)依次类推,最后到自定义类加载器指定的路径还没有找到Test.class字节码,则抛出异常ClassNotFoundException

你可能感兴趣的:(2019-07-11)