【JVM】关于类加载器准备阶段的一道面试题目
一个经典的延伸问题
我们来看一个经典的延伸问题,准备阶段谈到静态变量,那么对于常量和不同静态变量有什么区别?
需要明确的是,没有人能够精确的理解和记忆所有信息,如果碰到这种问题,有直接答案当然最好;没有的话,就说说自己的思路。
我们定义下面这样的类型,分别提供了普通静态变量、静态常量,常量又考虑到原始类型和引用类型可能有区别。
public class CLPreparation {
public static int a = 100;
public static final int INT_CONSTANT = 1000;
public static final Integer INTEGER_CONSTANT = Integer.valueOf(10000);
}
编译并反编译一下:
Javac CLPreparation.java
Javap –v CLPreparation.class
可以在字节码中看到这样的额外初始化逻辑:
0: bipush 100
2: putstatic #2 // Field a:I
5: sipush 10000
8: invokestatic #3 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
11: putstatic #4 // Field INTEGER_CONSTANT:Ljava/lang/Integer;
这能让我们更清楚,普通原始类型静态变量和引用类型(即使是常量),是需要额外调用 putstatic
等 JVM
指令的,这些是在显式初始化阶段执行,而不是准备阶段调用;而原始类型常量,则不需要这样的步骤。
本博客用于技术学习,所有资源都来源于网络,部分是转发,部分是个人总结。欢迎共同学习和转载,转载请在醒目位置标明原文。如有侵权,请留言告知,及时撤除。