乐趣区

关于JVM:面试知识点学习4反射机制类加载时的内存布局

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  
退出移动版