基本说明:
反射机制是java实现动态语言的关键,也就是通过反射实现类动态加载
- 静态加载:编译时 加载相关的类,如果没有则报错,依赖性太强
- 动态加载,运行时加载需要的类,如果运行时不用该类,则不会报错,降级了依赖性
类加载时机:
- 当创建对象时(new)
- 当子类被加载时
- 调用类的中的静态成员时
-
类加载过程图
加载阶段
JVM在该阶段的主要目的是将字节码从不同的数据源(class文件,jar包,网络)转化为二进制字节流加载到内存中,并生成一个代表该类的java.lang.Class对象
连接阶段
验证
目的是 为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全
- 包括:文件格式验证(是否以魔数 oxcafebabe 开头)、元数据验证,字节码验证和符号引用验证
- 可以考虑使用 -Xverify:none 参数 来关闭大部分的类验证措施,缩短虚拟机类加载的时间
准备
- JVM会在该阶段对静态变量分配内存并默认初始化(对应数据类型的默认初始化值)。这些变量所使用的内存都将在方法区中进行分配
解析
初始化阶段
- 到初始化阶段,才真正开始执行类中定义的Java程序代码,系阶段是执行
()方法的过程 ()方法是由编译器按语句在源文件中出现的顺序,依次自动收集类中所有的静态变量的赋值动作和静态代码块中的语句,并进行合并 - 虚拟机会保证一个类的
()方法在多线程环境中被正确的加锁、同步,如果多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的 ()方法,其他线程都需要阻塞等待,指导活动线程执行 ()方法完毕
- 加载B类,并生成B的Class对象
- 连接 num = 0
- 初始化阶段
System.out.println(B.num);//100如果直接使用类的静态属性,也对导致类的加载
new B();
加载类时的同步机制
B b = new B();