关于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回答
-
变量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在堆上,所以==的结果不一样。
042020-03-28
相似问题