注意
- instanceKlass 这样的【元数据】是存储在方法区(1.8 后的元空间内),但 _java_mirror 是存储在堆中
- 可以通过前面介绍的 HSDB 工具查看

验证类是否符合 JVM规范,安全性检查
修改 Verify.java 的魔数:将 cafebabe 修改为 cafebaby

解释执行结果:类格式错误
PS F:\software\IDEA\JavaProjects\JvmTest\target\classes\org\example\classLoading\link> java Verify
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.ClassFormatError: Incompatible magic value 1128351301 in class file Verify
at java.lang.ClassLoader.defineClass1(Native Method)
...
为 static 变量分配空间,设置默认值
将自己在其他类的常量池中的符号引用解析为直接引用
类A没有解析为直接引用
public class Analysis{
public static void main(String[] args) throws IOException {
//1.访问类A的静态变量(基本类型、字符串)不会导致类A的初始化(解析)
System.out.println(A.a);
System.in.read();
}
}
class A{
final static int a=1;
static int b=1;
static {
System.out.println("init");
}
}
运行程序
执行命令行命令,查看当前进程id
PS F:\software\IDEA\JavaProjects\JvmTest> jps
13816 Analysis
...
进入 jdk 安装目录,执行命令打开 HSDB工具
F:\software\Java\jdk1.8.0_333>java -cp ./lib/sa-jdi.jar sun.jvm.hotspot.HSDB
将 HSDB工具 链接到当前进程

找到 Analysis 类的常量池,查看类A的引用

类A解析为直接引用
public class Analysis{
public static void main(String[] args) throws IOException {
//2.访问类变量导致初始化
System.out.println(A.b);
System.in.read();
}
}
class A{
final static int a=1;
static int b=1;
static {
System.out.println("init");
}
}
运行程序
执行命令行命令,查看当前进程id
PS F:\software\IDEA\JavaProjects\JvmTest> jps
4768 Analysis
...
进入 jdk 安装目录,执行命令打开 HSDB工具
F:\software\Java\jdk1.8.0_333>java -cp ./lib/sa-jdi.jar sun.jvm.hotspot.HSDB
将 HSDB工具 链接到当前进程

找到 Analysis 类的常量池,查看类A的引用

初始化即调用
()V ,虚拟机会保证 ()V 的线程安全
导致类初始化的情况:
不会导致类初始化的情况 :
验证:导致类初始化的情况
public class Init {
static {
//1.main方法所在类。首先被初始化
System.out.println("1.init:main方法所在类");
}
public static void main(String[] args) throws ClassNotFoundException {
//2.new
A newTest=new A();
//3.子类初始化
//4.访问类的 静态变量、静态方法
int a=B.b;
//5.Class.forName(String)
Class.forName("org.example.classLoading.link.D");
}
}
class A{
static {
System.out.println("2.init:new的类");
}
}
class B extends C{
static int b=1;
static {
System.out.println("4.init:访问类的静态变量、静态方法");
}
}
class C{
static {
System.out.println("3.init:子类初始化");
}
}
class D{
static {
System.out.println("5.init:Class.forName(String)");
}
}
1.init:main方法所在类
2.init:new的类
3.init:子类初始化
4.init:访问类的静态变量、静态方法
5.init:Class.forName(String)
验证:不会导致类初始化的情况
public class Init {
public static void main(String[] args) throws ClassNotFoundException {
ClassLoader classLoader = Init.class.getClassLoader();
//1.类加载器的 loadClass 方法 :加载阶段
classLoader.loadClass("org.example.classLoading.link.A");
//2.Class.forName(String,false) :加载阶段
Class.forName("org.example.classLoading.link.A",false,classLoader);
//3.创建该类的数组不会触发初始化 :加载阶段
A[] arr=new A[2];
//4.访问 类.class :加载阶段
Class<A> clazz = A.class;
//5.访问类的 静态常量(基本类型和字符串) :链接-准备阶段
int a=A.a;
}
}
class A{
static final int a=1;
static {
System.out.println("init A");
}
}
Process finished with exit code 0