小编给大家分享一下java中常量折叠的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
成都创新互联于2013年创立,先为城厢等服务建站,城厢等地企业,进行企业商务咨询服务。为城厢企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。
实例解析
让我迷惑的代码是下面这段代码
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、第二个栗子
public static void main(String[] args) { String a = "a"; String bc = "bc"; String s1 = "a" + "bc"; String s2 = a + bc; System.out.println(s1 == s2); }
这个结果呢?false
s1 是字符串字面量相加,但是 s2 却是两个非 final 的变量相加,所以不会进行常量折叠。
而是根据 String 类特有的 + 运算符重载,变成类似这样的代码
String s2 = new StringBuffer(a).append(b).toString();
这里toString()会生成新的String变量,显然用 == 运算符比较是会返回 false。
3、第三个栗子
public static void main(String[] args) { final String a = "a"; final String bc = "bc"; String s1 = "a" + "bc"; String s2 = a + bc; System.out.println(s1 == s2); }
这里的结果就是true
因为 被编译器常量赋值的 final 的基本类型和字符串变量也是编译期常量
4、第四个栗子
public static void main(String[] args) { String x ="a"; final String a = x; final String bc = "bc"; String s1 = "a" + "bc"; String s2 = a + bc; System.out.println(s1 == s2); }
这里的结果是false
这里需要注意的是:final的变量,不是被编译期常量初始化的也不是编译器常量
这里的a 就不是编译器常量
以上是“java中常量折叠的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注创新互联行业资讯频道!