类加载生命期:加载(Loading),验证(Verification),准备(Preparation),解析(Resolution),初始化(Initialization),使用(Using),卸载(Unloading)初始化:1.遇到new,getstatic,putstatic,invokestatic指令,类没有进行初始化,先触发初始化2.java反射机制3.初始化一个类,父类没有初始化,需要先触发父类的初始化4.JVM启动的时候,用户需要指定一个执行的主类(main所在的位置),JVM优先初始化5.JDK1.7动态语言支持注:1.只有直接定义静态字段(static int i=1;)的类才会被初始化,而(static{sysout("Hello")})并不会触发初始化2.类在初始化的时候必须要求其父类初始化,但是接口不需要,只有真正使用到父类接口,父类接口才会初始化加载:1.通过一个类的全限定名来获取定义此类的二进制字节流//因此可从jar,war,网络获取类结构2.将这个字节流所代表的静态结构转化为方法区的运行时数据结构3.在内存中生成一个代表这个类的java.lang.Class对象,作为方法区的访问入口注:类加载的过程可以通过系统的类加载器来完成,也可以自定义类加载器控制字节流获取方式加载阶段完成之后,类的字节流文件按照JVM的格式(格式由JVM定)储存在方法区中,然后在内存中实例化一个java.lang.Class对象对于HotSpot来说,该对象存放在方法区中,这个对象将作为程序访问的方法区数据类型的接口验证:确保Class文件的字节流中包含的信息不会损害JVM1.格式验证:是否以魔数开头,主次版本号,常量池中是否有不支持常量的类型,编码情况,Class文件是否具有附加信息.....2.元数据验证:检查是否符合Java语言规范3.字节码验证:验证类型转换4.符号引用验证:字符串限定符,类字段,方法的限定符准备:为类变量(静态变量)分配内存,设置初值(默认0/false/null),实例变量的初始化跟随对象一起分配到Java堆中解析:将符号引用(通过一组符号描述引用目标,符号引用的实现与内存布局无关)替换为直接引用(直接指向目标的指针/句柄)解析动作主要针对类或接口,字段,类方法,接口方法,方法类型,方法句柄,和调用限定符7类符号引用进行,分别对应常量池的CONSTANT_Class_info,CONSTANT_Fieldref_info,CONSTANT_Methodref_info,CONSTANT_InterfaceMethodref_info,CONSTANT_MethodType_info,CONSTANT_MethodHandle_info和CONSTANT_InvokeDynamic_info 7中类型字段解析,类方法解析,接口方法解析初始化(类加载过程最后一步//初始化阶段的过程就是执行类构造器<climit>()方法的过程):<climit>()方法是由编译器自动收集类中所有变量的赋值动作和静态语句块(static{}块)中的语句合并产生,编译器收集的顺序是由语句在源文件中出现顺序决定例:public class Test {static{i = 0;//静态代码块中的i可以被赋值,但不能被访问(非法向前引用)正常编译System.out.println(i);//报 illegal forward reference(非法向前引用)}static int i = 1;//如果要访问i,应该将i在静态代码块前面进行声明}<climit>()方法与类的构造方法(<init>()方法)不同,它不需要显示地调用父类构造器,虚拟机保证在子类的<climit>()方法执行之前,父类的<climit>()方法已经执行完毕,因此在JVM中第一个被执行的<climit>()方法的类肯定是java.lang.Object由于<climit>()先执行,所以静态语句块优先加载例:static class parent{public static int a=1;static{a=2;}}static class sub extends parent{public static int b=a;//此时b会被初始化为2}注:<climit>()对于类或接口来说,不是必须的,当类中没有静态语句块,没有对类变量赋值操作,编译器将不会生成<climit>方法接口中不能使用静态语句块,但可以有变量赋值操作,说明接口和类都一样会生成<climit>(),接口与类不同的是,接口中不需要先执行父类的<climit>(),只有使用父接口才会去初始化JVM会保证一个类的<climit>()在多线程的环境中被正确加锁,同步,多个线程同时初始化一个类,将只会有一个线程去执行类的<climit>(),其他线程阻塞,直到线程活动执行完<climit>()完毕,就此会造成线程阻塞问题(并且很隐蔽)类加载器双亲委派模型前序:启动类加载器(Bootstrap ClassLoader)//C++语言实现,JVM自身一部分,主要作用是将放在<JAVA_HOME>\lib目录中/被-Xbootclasspath参数指定的路径的类库(要被JVM识别)加载到JVM内存中扩展类加载器(Extension ClassLoader):由sun.misc.Launcher$ExtClassLoader实现,用于加载<JAVA_HOME>\lib\ext目录中/java.ext.dirs系统变量所指定的路径中所有类库应用程序加载器:加载用户类路径上指定类库最后加载器为自定义加载器上述加载器除Bootstrap ClassLoader统称为其他类加载器//由java语言实现,独立于虚拟机外部,继承于抽象类java.lang.ClassLoader双亲委派模型(强制性约束模型):一个类收到加载请求首先会委派父类加载器完成,直到请求传送到顶层启动类加载器中,只有当父类反馈无法完成加载请求,子类加载器才会尝试加载,保证程序的稳定运行OSGi环境下,类加载器不再是树状模型,而是网状,他会采用同级之间的类进行加载