一、java类初始化发生的情况:
1.通过类名调用静态方法或静态变量
2.new 该类对象,反序列化该类,clone时,class.newInstance等(总的来说就是创建该类对象时)
3.通过反射生成该类 譬如class.forName("类名")
二、类初始化过程
1.加载类
2.连接
a.验证 (校验类是否正确,比如语法等)
b.准备 (为静态变量,方法分配内存,并赋予静态变量系统默认的初始值)
c.解析 (主要将常量池中的符号引用替换为直接引用的过程。符号引用就是一组符号来描述目标,可以是任何字面量,而直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。有类或接口的解析,字段解析,类方法解析,接口方法解析(这里涉及到字节码变量的引用)
3.初始化 (初始化静态变量,即写该类时赋予的初始值)
三、类加载过程
类是通过类加载器来加载的,加载器分为三个:
1.bootStrapClassLoader 根加载器 :主要用来加载java的核心类 (<JAVA_HOME>/lib路径下的核心类库),该加载器并不是 java实现的而是C++
2.ExtClassLoader 扩展加载器 :主要用来加载一些扩展类 (负责加载<JAVA_HOME>/lib/ext目录下或者由系统变量-Djava.ext.dir指定位路径中的类库),它是java实现的
3.ApplicationClassLoader 系统加载器 (用来负责加载系统类路径java -classpath或-D java.class.path 指定路径下的类库,也就是我们经常用到的classpath路径),它是java实现的,我们自定义的类加载器继承该加载器
在上述的三个类加载器中,根加载器 为 扩展加载器 的父加载器,扩展加载器 为 系统加载器 的父加载器,但他们之间并不是继承的关系,而是持有的关系,扩展加载器 持有 根加载器 ,系统加载器 持有 扩展加载器 。如果加载器收到一个加载类的请求,那么他会委托自己的父加载器去加载,一直会被委托到bootStrapLoader。如果bootStrap不能加载该类,则委托给Ext,如果Ext不能加载则给app,这样顺推。同时这里要说明的是被根加载器加载过的类不会再被扩展加载器之后的加载器加载,被扩展加载器加载的类不会在被系统加载器之后的加载器加载。这就是加载器的双亲委托机制。