BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #42904同步于 2015/7/20
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

[已解决][问题]String中的+对final做了什么优化?

yizhe
2015/7/20镜像同步4 回复
public class Test { public static void main(String[] args){ testFinal(); } public static void testFinal(){ String s1 = "ab"; String s2 = "a"; String s4 = s2 + "b"; System.out.println(s1==s4);//false final String s3 = "a"; String s5 = s3 + "b"; System.out.println(s1==s5);//true } } 如上代码,加了final之后,结果就是相同的,是重载之后的+对final类型做了什么优化吗? 汇编之后的代码如下所示,明显是不加final的+引入了StringBuilder,所以不相同。但是为什么加了final之后就直接出来ab了呢? Compiled from "Test.java" public class com.Test.Test { public com.Test.Test(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: invokestatic #2 // Method testFinal:()V 3: return public static void testFinal(); Code: 0: ldc #3 // String ab 2: astore_0 3: ldc #4 // String a 5: astore_1 6: new #5 // class java/lang/StringBuilder 9: dup 10: invokespecial #6 // Method java/lang/StringBuilder."<init>":()V 13: aload_1 14: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 17: ldc #8 // String b 19: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 22: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 25: astore_2 26: getstatic #10 // Field java/lang/System.out:Ljava/io/PrintStream; 29: aload_0 30: aload_2 31: if_acmpne 38 34: iconst_1 35: goto 39 38: iconst_0 39: invokevirtual #11 // Method java/io/PrintStream.println:(Z)V 42: ldc #4 // String a 44: astore_3 45: ldc #3 // String ab 47: astore 4 49: getstatic #10 // Field java/lang/System.out:Ljava/io/PrintStream; 52: aload_0 53: aload 4 55: if_acmpne 62 58: iconst_1 59: goto 63 62: iconst_0 63: invokevirtual #11 // Method java/io/PrintStream.println:(Z)V 66: return }
订阅后,新回复会通过你的通知中心匿名送达。
4 条回复
icyfox机器人#1 · 2015/7/20
http://stackoverflow.com/questions/16783971/string-constant-pool-vs-string-pool see amicngh's answer. Because s3 is final , s5 is considered as final , so s5 is saved in constant poll when compile. so s5 == s1; reference: http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.18.1 The String object is newly created (§12.5) unless the expression is a compile-time constant expression (§15.28).
newxiaohao机器人#2 · 2015/7/20
public static void testFinal(){ String s1 = "ab"; String s2 = "a"; String s4 = s2 + "b"; System.out.println(s1==s4);//false final String s3 = "a"; String s5 = s3 + "b"; System.out.println(s1==s5);//true } 第一个输出false是因为s2在编译期间是不能被确定的,所以无法将s4字符串对应到常量池,因此输出false 第二个输出true,是因为加了final以后,凡是出现了s3的地方都会被替换成a,相当于s5="a"+"b";会在编译期间就对应到常量池 懂了没 【 在 yizhe 的大作中提到: 】 : [code=java] : public class Test { : public static void main(String[] args){ : ...................
yizhe机器人#3 · 2015/7/20
many thanks 【 在 icyfox 的大作中提到: 】 : http://stackoverflow.com/questions/16783971/string-constant-pool-vs-string-pool : see amicngh's answer. : Because s3 is final , s5 is considered as final , so s5 is saved in constant poll when compile. : ...................
yizhe机器人#4 · 2015/7/20
懂了,加final之后其他地方就会自动替换了 【 在 newxiaohao 的大作中提到: 】 : public static void testFinal(){ : String s1 = "ab"; : String s2 = "a"; : ...................