public class C {
String s1 = "a";
String s2 = "a"+"b";
public static void main(String args[]){
}
}
在编译时其,如果+ 操作符两边都是常量,那么在编译后将其连接的值放入常量 池中,也就是将 ab 放入常量池,你不会找到常量 b
编译后的指令为:
public C();
Code:
Stack=2, Locals=1, Args_size=1
0: aload_0 // 返回值this
1: invokespecial #11; //Method java/lang/Object."<init>":()V // 调用 this.<init>
4: aload_0 // 返回this
5: ldc #13; //String a // 得到常量池中的 a
7: putfield #15; //Field s1:Ljava/lang/String; // 设置 字段s1 的值
10: aload_0 // 返回 this
11: ldc #17; //String ab // 返回常量中的 ab
13: putfield #19; //Field s2:Ljava/lang/String; // 设置 字段 s2
16: return
上面是对于 + 操作数都为常量而言的,如果为变量,那么怎么样?
如果为变量的话,它会 new StringBuilder 出来进行append,然后返回 toString()
public C();
Code:
Stack=4, Locals=1, Args_size=1
0: aload_0
1: invokespecial #11; //Method java/lang/Object."<init>":()V
4: aload_0
5: ldc #13; //String a
7: putfield #15; //Field s1:Ljava/lang/String;
10: aload_0 //以上都一样,对 字段 s1 进行赋值
11: new #17; //class java/lang/StringBuilder //创建一个 stringBuilder 对象
14: dup //复制栈项值并将复制值压入栈顶
15: aload_0 // 得到当前对象
16: getfield #15; //Field s1:Ljava/lang/String; // 得到字段s1
19: invokestatic #19; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; //调用 String.valueOf
22: invokespecial #25; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V // 调用 StringBuilder 构造
25: ldc #28; //String b //从常量池中取出 b
27: invokevirtual #30; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;// 调用stringBuilder 中的 append 方法
30: invokevirtual #34; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; // 返回 stringBuilder 中的 toString()
33: putfield #38; //Field s2:Ljava/lang/String; // 设置字段 s2
36: return
LineNumberTable: