常量池

2020-01-17  本文已影响0人  couriravant

Java中的常量池,实际上分为两种形态:静态常量池和运行时常量池。

静态常量池 : *.class文件中的常量池,class文件中的常量池不仅仅包含字符串(数字)字面量,还包含类、方法的信息,占用class文件绝大部分空间。(编译时期)

运行时常量池 : jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在方法区中,我们常说的常量池,就是指方法区中的运行时常量池。(运行时期)
补充 : 运行时常量池中的常量,基本来源于各个class文件中的常量池。(即每个class文件都有对应的常量池)

比如static final 、final修饰的基本类型会在编译期生成在class文件中(其中static final 生成的常量会保存在调用类的class文件中,所以调用static final 修饰的变量,不会造成所在类的加载),但是调用static变量会造成所在类的加载。

public class Deal {
    static {
        System.out.println("加载了 deal");
    }
    static final int x = 1000;
    final int y = 100;
    static int mm = 20000;

    Deal() {
        System.out.println("加载了 构造函数");
    }

    public static final String str = UUID.randomUUID().toString();
}

public class Try {
    public static void main(String[] args) {
        System.out.println(Deal.x);
//        System.out.println(Deal.str);   
    }
}

输出:

1000

Process finished with exit code 0

System.out.println(Deal.str); 对应的输出(同调用Deal.mm):

1000
加载了 deal

编译器对于静态field字段的初始化赋值策略:

如果final和static同时修饰一个字段,并且这个字段是基本类型或者String类型的,
那么编译器在编译这个字段的时候,会在对应的field_info结构体中增加一个ConstantValue类型的结构体,在赋值的时候使用这个ConstantValue进行赋值;如果该field字段并没有被final修饰,或者不是基本类型或者String类型,那么将在类构造方法中赋值。
final和static:
final可以在编译(类加载)时初始化,也可以在运行时初始化;static在类加载时初始化
非final的成员变量在堆里,final类型的成员变量存放在方法区的常量池中。
refer:https://blog.csdn.net/dhaiuda/article/details/79202160
https://cloud.tencent.com/developer/article/1450501
https://juejin.im/entry/5a51d2656fb9a01cb912b91f

https://www.jianshu.com/p/1f4b0f98cbf1
内存泄漏:https://www.jianshu.com/p/f35ca324c285

上一篇 下一篇

猜你喜欢

热点阅读