类的生命周期
- 加载
- 连接(验证、准备、解析)
- 解析也有可能在初始化之后再开始(动态绑定)
- 初始化
- 遇到new、getstatic、putstatic、invokestatic4条字节码指令时(static without final)
- 使用java.lang.reflect包的方法对类进行反射调用时
- 初始化一个类时,如果父类还没有初始化,则触发父类的初始化(接口不会)
- 用户指定执行的main类,虚拟机会先初始化
- 使用jdk7的动态语言支持时(java.lang.invoke.MethodHandle)
- tips
- 对于静态变量,只有直接定义这个字段的类才会被初始化
- newarray指令不触发初始化
- 引用常量不触发初始化
- 是执行< clinit >()方法的过程
- 所有类变量的赋值动作和静态语句块合并产生的
- 父类的< clinit >()会先执行
- 使用
- 卸载
类加载器
通过一个类的全限定名来获取描述此类的二进制字节流
每一个类,都需要由加载它的类加载器和这个类本身一同确认它在JVM中的唯一性
- 启动类加载器
- 扩展类加载器
- 应用程序类加载器(默认)
- 自定义类加载器
双亲委派模型
- 除了顶层的启动类加载器外,其余的类加载器都应当有自己的父类加载器
- 如果一个类加载器收到类加载的请求,首先委派给父类加载器完成,当父类加载器无法完成时,子类加载器才尝试自己加载
- Java类随着它的类加载器一起具备了一种带有优先级的层次关系,保证了程序的稳定运作