返回信息流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
}
这是一条镜像帖。来源:北邮人论坛 / java / #42904同步于 2015/7/20
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
[已解决][问题]String中的+对final做了什么优化?
yizhe
2015/7/20镜像同步4 回复
订阅后,新回复会通过你的通知中心匿名送达。
4 条回复
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).
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){
: ...................
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.
: ...................
懂了,加final之后其他地方就会自动替换了
【 在 newxiaohao 的大作中提到: 】
: public static void testFinal(){
: String s1 = "ab";
: String s2 = "a";
: ...................