请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

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

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回答

变量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 回复 有任何疑惑可以回复我~
  • 提问者 woy #1
    非常感谢!
    回复 有任何疑惑可以回复我~ 2020-02-19 15:57:46
  • 悟空老师 ,那这个代码除了d上加final以外,还有什么方法可以打印出都是true
    回复 有任何疑惑可以回复我~ 2020-03-25 17:20:52
  • 其他方法不清楚
    回复 有任何疑惑可以回复我~ 2020-03-25 17:53:02
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信