4 反射机制、类加载时的内存布局
4.1 学习材料——B站韩顺平
【韩顺平讲Java】Java反射专题 -反射 反射机制 类加载 reflection Class 类构造 等_哔哩哔哩_bilibili
4.2 动态加载/动静加载
- 动态加载:编译时加载相干的类,如果没有则报错,依赖性强
- 动静加载:运行时加载须要的类,如果运行时不必该类,即便不存在该类也不报错,升高了依赖性。
反射是动静加载,编译时不会报错,只有当代码执行到相应的代码时才会报错
4.3 类加载机会(只有反射是动静加载)
4.4 类加载过程
4.4.1 加载
将字节码从不同的数据源(可能是class文件,也可能是jar包,甚至是网络)转化为二进制字节流加载到内存中(办法区中),并生成一个代表该类的java.lang.Class对象。
4.4.2 连贯—验证
4.4.3 连贯—筹备
==动态变量==调配内存(办法区中调配),默认初始化(不论给什么值,先依照对应的数据类型的默认值初始化,如0、0L、null、false等);
筹备阶段代码示例:(n2在初始化时赋值为20)
4.4.4 连贯—解析
虚拟机把常量池中的符号援用替换成间接援用;
假如A类援用B类,编译时应用的符号来援用,比方1援用2;解析后有内存地址,变成了A的地址援用B的地址。
4.4.5 初始化
显式(指定)初始化,程序员可管制;
代码示例:
剖析:
- 1.加载B类,生成B的Class对象;
- 2.链接:num=0;
3.初始化:顺次收集类中所有动态变量的赋值动作和动态代码块中的语句:
clinit(){ System.out.println(“B动态代码块被执行”); num=300; num=100;}进行合并:num=100
补充:
如果main函数是这样的:
public static void main(String[] args) { System.out.println(B.num);}
此时间接应用类的动态属性,则不执行结构器办法,也会有类的加载,输入为:
B动态代码块被执行100
如果main函数是这样的:
public static void main(String[] args) { new B(); System.out.println(B.num);}
输入为:
B() 结构器被执行B动态代码块被执行100