——————————————————————
加载 Loading
验证 Verification |
准备 Preparation | 连接 Linking
解析 Resolution |
初始化 Initialization
使用 Using
卸载 Unloading
————————————————————————
解析的顺序不一定,可以在初始化阶段之后再开始,支持运行时绑定
1.new getstatic putstatic (final除外) invokestatic
2.使用java.lang.reflect包的方法对类进行反射调研
3.初始化子类触发父类初始化 (真正使用到父接口时,如定义的常量)
4.虚拟机启动,用户执行主类(包含main方法)
被动引用,不触发初始化方法:
1.通过子类引用父类的静态字段
2.通过数组定义来引用类
3.常量在编译阶段会存入调用类的常量池中,本质上没有直接引用到定义常量的表
=================================================
1.通过一个类的权限定名来获取定义此类的二进制字节流 zip jar war applet proxy jsp db
2.将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
3.在Java堆中生成一个代表这个类的java.lang.Class对象,作为方法区这些数据的访问入口
1.文件格式验证 正确解析并存储在方法区
2.元数据验证 语义校验,符合Java语言规范
3.字节码验证 数据流和控制流分析 Halting Problem 1.6 -XX: -UseSplitVerifier关掉优化
4.符号引用验证 符号引用中全限定名,符号描述,访问性 -Xverify:none
正式为类变量分配内存并设置类变量初始值,在方法区分配。
注意实例变量和对象一起分配在堆中,不在这一过程。
final常量将会赋值,其他都是初始值 0 false ...
1.类或接口解析
2.字段解析
3.类方法解析
4.接口方法解析
执行类构造器<clinit>
1.顺序收集所有类变量赋值动作和静态块
2.虚拟机会保证先调父类<clinit>
3.虚拟机会保证一个类<clinit>在多线程下加锁和同步
=================================================
1.类与加载器确认唯一性
2.双亲委派模型 Parents Delegation Model
启动类加载器 Bootstrap ClassLoader
扩展类加载器 Extension ClassLoader
应用程序类加载器 Application ClassLoader
自定义类加载器 User ClassLoader
除了顶层的启动类加载器外,其他都有自己的父类加载器,
父子关系使用组合来复用父加载器代码,优先调父类加载器加载类
3.非双亲委派模型
向前兼容,重写loadClass()
线程上下文类加载器 Thread Context ClassLoader JNDI JDBC JCE
程序动态性,代码热替换HotSwap
1.将以java.*开头的类,委派给父类加载器加载
2.否则,将委派列表名单内的类,委派给父类加载器加载
3.否则,将Import列表中的类,委派给Export这个类的Bundle的类加载器加载
4.否则,查找当前Bundle的ClassPath,使用自己的类加载器加载
5.否则,查找类是否在自己的Fragment Bundle中,如果在,则委派给Fragment Bundle的类加载器加载
6.否则,查找Dynamic Import列表的Bundle,委派给对应的Bundle的类加载器加载
7.否则,类查找失败