为什么会写着篇博客,因为昨天看了关于final关键字的解析。但是有个问题始终没有得到解决,于是请教了我qq上之前添加的知乎大神。他给我回复的第一条消息:常量折叠。身为渣渣猿的我立马查询了这个概念。这是第一次知道这个概念。知乎大神还给我讲了好多。让我终于明白了这个常量折叠的概念
实例解析
昨天,让我迷惑的代码是下面这段代码
public static void main(String[] args) { String a = "hello2"; final String b = "hello"; String d = "hello"; String c = b + 2; String e = d + 2; System.out.println((a == c)); System.out.println((a == e)); }这段的执行结果是
true false我就是不明白为什么第一个返回true呢?
留着这个疑问,我们先了解下常量折叠的概念。来更好的理解上面的代码
常量折叠
常量折叠的概念
- 常量折叠是一种
编译器优化技术。 - 常量折叠主要指的是
编译期常量加减乘除的运算过程会被折叠
对于 String s1 = "1" + "2";
编译器会给你优化成 String s1 = "12";
在生成的字节码中,根本看不到 "1" "2" 这两个东西。
我们通过idea进行验证下
1、源码文件
public static void main(String[] args) { String s1 = "1"+"2"; }2、运行后,idea有个out文件夹,找到上面文件的class文件
public static void main(String[] args) { String s1 = "12"; }确实如上面所说,编译器会给你进行优化
常量折叠发生的条件
- 必须是编译期常量之间进行运算才会进行常量折叠。
- 编译期常量就是“编译的时候就可以确定其值的常量”,
- 首先:字面量是
编译期常量。(数字字面量,字符串字面量等) - 其次:编译期常量进行
简单运算的结果也是编译期常量,如1+2,"a"+"b"。 - 最后:被编译器常量
赋值的 final 的基本类型和字符串变量也是编译期常量。
- 首先:字面量是
举个栗子
1.第一个栗子
public static void main(String[] args) { String s1="a"+"bc"; String s2="ab"+"c"; System.out.println(s1 == s2); }相信大家都知道了,输出为true
并且只创建了一个 "abc" 字符串对象,且位于字符串常量池中。
2、第二个栗子
