一、前言
1.JVM类加载机制分为五个部分:加载->链接(验证+准备+解析)->初始化(使用前的准备)->使用->卸载(如下图),
2.类加载器分类及层级关系如下图
引导类加载器(bootstrap class loader)@b@@b@--他用类加载java 的核心库(String 、Integer、List。。。)在jre/lib/rt.jar路径下的内容,是用C代码来实现的,并不继承自java.lang.ClassLoader。@b@@b@--加载扩展类和应用程序类加载器。并指定他们的父类加载器。@b@@b@扩展类加载器(extensions class loader)@b@@b@--用来加载java的扩展库(jre/ext/*.jar路径下的内容)java虚拟机的实现会自动提供一个扩展目录。该类加载器在此目录里面查找并加载java类。@b@@b@ 应用程序类加载器(application class loader)@b@@b@--他根据java应用的类路径(classpath路径),一般来说,java应用的类都是由他来完成加载的@b@@b@自定义类加载器@b@@b@--开发人员可以通过继承java.lang.ClassLoader类的方式实现自己的类加载器,以满足一些特殊的需求。
3.JVM完整系统执行过程,如下图所示
二、类的主动引用、被动引用分类
1.类的主动引用(一定会发生类的初始化)
--new一个类的对象@b@@b@--调用类的静态成员(除了final常量)和静态方法@b@@b@--使用java.lang.reflect包的方法对类进行反射调用@b@@b@--当初始化一个类,如果其父类没有被初始化,则先初始化他的父类@b@@b@--当要执行某个程序时,一定先启动main方法所在的类
2.类的被动引用(不会发生类的初始化)
--当访问一个静态变量时,只有真正生命这个静态变量的类才会被初始化(通过子类引用父类的静态变量,不会导致子类初始化)@b@@b@--通过数组定义类应用,不会触发此类的初始化 A[] a = new A[10];@b@@b@--引用常量(final类型)不会触发此类的初始化(常量在编译阶段就存入调用类的常量池中了)
三、类加载器使用
1、获取类加载器方式
//方法一@b@this.getClass.getClassLoader(); @b@//方法二@b@Thread.currentThread().getContextClassLoader();
2. 变更类加载器
Thread.currentThread().setContextClassLoader(myclassLoader);