关于String变量放在常量池还是堆的疑问

来源:8-5 相关面试题

woy

2020-02-17

public class FinalStringDemo1 {

    public static void main(String[] args) {
        String a = "wukong2";
        final String b = "wukong";
        String d = "wukong";
        String c = b + 2;
        String e = d + 2;
        System.out.println((a == c));
        System.out.println((a == e));
    }
}

老师, 我想问下, 你说a和c都是放在常量池中, 那d也应该是放在常量池, 但到了e为啥它就放在堆里了呢?
我的理解是a和d不是常量, 所以他俩是在程序运行时才进行赋值, 那在运行时创建的值不应该放在堆上么?

写回答

1回答

悟空

2020-02-17

变量a指的是字符串常量池中的 wukong2;

当final变量是基本数据类型以及String类型时,如果在编译期间能知道它的确切值,也就是提前知道了b的值,所以则编译器会把它当做编译期常量使用。也就是说在用到该final变量的地方,相当于直接访问的这个常量,不需要在运行时确定,和C语言中的宏替换有点像。因此在上面的一段代码中,由于变量b被final修饰,因此会被当做编译器常量,所以在使用到b的地方会直接将变量b 替换为它的 值。而对于变量d的访问却需要在运行时通过链接来进行。

变量 c 是 b + 2得到的,由于 b 是一个常量,所以在使用 b 的时候直接相当于使用 b 的原始值(wukong)进行计算,所以 c 生成的也是一个常量,而a 也是常量,a和c都是 wukong2,由于 Java 中常量池中只生成唯一的一个 wukong2字符串,所以 a 和 c 是==的。

但是d 的情况有所不同,d是指向常量池中 wukong,但由于 d 不是 final 修饰,也就是说编译器在使用 d 的时候不会提前知道 d 的值,所以在计算 e 的时候也需要在运行时才能确定,所以这种计算会在堆上生成 wukong2,所以最终 e 指向的是堆上的,所以 a 和 e 不相等。

 

总结:a和c在常量池,e在堆上,所以==的结果不一样。

0
4
慕桂英1135072
回复
菜鸟小oneone
String e = d + 2; 改为 String e = "wukong" + 2; 这样都是true
2020-03-28
共4条回复

深度解密Java并发工具,精通JUC,成为并发多面手

JUC全方位讲解,构建并发工具类知识体系

1599 学习 · 573 问题

查看课程