Ank*_*and 17 java string final
当我编译这个片段.
public class InternTest {
public static void main(String...strings ){
final String str1="str";
final String str2="ing";
String str= str1+str2;
}
}
Run Code Online (Sandbox Code Playgroud)
其中产生以下字节代码
public static void main(java.lang.String...);
flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS
Code:
stack=1, locals=4, args_size=1
0: ldc #16 // String str
2: astore_1
3: ldc #18 // String ing
5: astore_2
6: ldc #20 // String string
8: astore_3
9: return
Run Code Online (Sandbox Code Playgroud)
所以字符串文字"字符串"已存在于常量池中,该字符串6: ldc #20 // String string在此行的堆栈上被推送.
引用JSL
来自JLS§4.12.4 - 最终变量:
原始类型或类型String的变量是final,并使用编译时常量表达式(第15.28节)初始化,称为常量变量.
同样来自JLS§15.28 - ConstantExpression:
String类型的编译时常量表达式总是"实例化",以便使用String#intern()方法共享唯一的实例.
所以我知道str1和str2将在创建时被实现."str"和"ing"将在行共享相同的内存String str= str1+str2;
但是str1 + str2如何直接在常量字符串池中生成"string".不调用任何String Builder类就像我不写时一样final.?看看它是否与实习生有关
我写了这个片段
public class IntermTest {
public static void main(String...strings ){
String str1=("str").intern();
String str2=("ing").intern();
String str= str1+str2;
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我生成字节码时,我得到了这个
public static void main(java.lang.String...);
flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS
Code:
stack=3, locals=4, args_size=1
0: ldc #16 // String str
2: invokevirtual #18 // Method java/lang/String.intern:
()Ljava/lang/String;
5: astore_1
6: ldc #24 // String ing
8: invokevirtual #18 // Method java/lang/String.intern:
()Ljava/lang/String;
11: astore_2
12: new #26 // class java/lang/StringBuilder
15: dup
16: aload_1
17: invokestatic #28 // Method java/lang/String.valueOf
:(Ljava/lang/Object;)Ljava/lang/String;
20: invokespecial #32 // Method java/lang/StringBuilder.
"<init>":(Ljava/lang/String;)V
23: aload_2
24: invokevirtual #35 // Method java/lang/StringBuilder.
append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
27: invokevirtual #39 // Method java/lang/StringBuilder.
toString:()Ljava/lang/String;
30: astore_3
31: return
Run Code Online (Sandbox Code Playgroud)
实际上它也stringBuilder用于连接.所以它已经做了最后的事情.关于final字符串有什么特别之处,我绝对不知道吗?
JB *_*zet 17
http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.28说
引用常量变量(第4.12.4节)的简单名称(第6.5.6.1节)是常量表达式.
http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.28也说:
常量表达式是表示基本类型值的表达式或不突然完成的字符串,仅使用以下内容组成:
- 原始类型的文字和String类型的文字(§3.10.1,§3.10.2,§3.10.3,§3.10.4,§3.10.5)
- [...]
- 加法运算符+和 - (§15.18)
- [...]
- 引用常量变量的简单名称(第6.5.6.1节)(§4.12.4).
例15.28-1.常数表达式
[...]
"整数"+ Long.MAX_VALUE +"非常大."
由于这两个变量是常量表达式,编译器会进行连接:
String str = str1 + str2;
Run Code Online (Sandbox Code Playgroud)
编译方式与.相同
String str = "str" + "ing";
Run Code Online (Sandbox Code Playgroud)
这与编译方式相同
String str = "string";
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4396 次 |
| 最近记录: |