[关闭]
@stefanlu 2016-03-04T03:27:20.000000Z 字数 819 阅读 2095

字符串拼接编译器自动优化

java


知乎

代码:

(一)
String s1="a"+"bc";
String s2="ab"+"c";
s1==s2的结果是true
(二)
String a="a";
String bc ="bc";
String s1="a"+"bc";
String s2=a + bc;
s1==s2的结果就是false

有一个东西叫做常量折叠,是一种编译器优化技术。
就是对于 String s1 = "1" + "2"; 编译器会给你优化成 String s1 = "12";
在生成的字节码中,根本看不到 "1" "2" 这两个东西。

常量折叠有什么条件?
必须是编译期常量之间进行运算才会进行常量折叠。
编译期常量就是“编译的时候就可以确定其值的常量”,而且这个认定比较严格。
首先:字面量是编译期常量。(数字字面量,字符串字面量等)
其次:编译期常量进行简单运算的结果也是编译期常量,如1+2,"a"+"b"。
最后:被编译器常量赋值的 final 的基本类型和字符串变量也是编译期常量。

对于你的问题(一)
s1 和 s2 都是字符串字面量相加,都是编译期常量,都会被编译器进行常量折叠。

对于你的问题(二)
s1 是字符串字面量相加,但是 s2 却是两个非 final 的变量相加,所以不会进行常量折叠。
而是根据 String 类特有的 + 运算符重载,变成类似这样的代码

String s2 = new StringBuffer(a).append(b).toString();

这里toString()会生成新的String变量,显然用 == 运算符比较是会返回 false。
(理解这里还需要字符串常量池的概念,以及 == 和 equals 的概念,我姑且认为你知道)


添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注