【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;

这能让我们更清楚,普通原始类型静态变量和引用类型(即使是常量),是需要额外调用 putstaticJVM 指令的,这些是在显式初始化阶段执行,而不是准备阶段调用;而原始类型常量,则不需要这样的步骤。

猜你喜欢

转载自www.cnblogs.com/z00377750/p/9238056.html