javap命令观察jvm对 String + 的优化情况

源代码:

public class Test{
    public static void main(String[]args){
        String x = "";
        for(int i=0;i<10;i++){
            x+="abc";
        }
        System.out.println(x);
    }
}

javap:反编译结果

public static void main(java.lang.String[]);
  Code:
   0:   ldc     #2; //String --ldc:常数到操作数栈 ""
   2:   astore_1               --astore:将引用类型或returnAddress类型值存入局部变量  String x = ""
   3:   iconst_0               --iconst_0:将int类型常量0压入栈                                                                              
   4:   istore_2               --istore:将int类型值存入局部变量   int i = 0   
   5:   iload_2                --iload:从局部变量装载int类型值  取出i
   6:   bipush  10             --bipush:将一个8位带符号整数压入栈  压入10
   8:   if_icmpge       37     --if_icmpge:如果一个int类型值大于或者等于另外一个int类型值,则跳转  执行i<10判断
   11:  new     #3; //class java/lang/StringBuilder
   14:  dup
   15:  invokespecial   #4; //Method java/lang/StringBuilder."<init>":()V
   18:  aload_1                --aload:从局部变量装载引用型数据  取出String x("");
   19:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/String
   22:  ldc     #6; //String abc
   24:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/String
   27:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   30:  astore_1               --astore:将引用类型或returnAddress类型值存入局部变量  将toString结果赋值给x
   31:  iinc    2, 1           --iinc:将一个常量值加到一个int类型的局部变量上  i+1
   34:  goto    5                                                                                                     
   37:  getstatic       #8; //Field java/lang/System.out:Ljava/io/PrintStream;
   40:  aload_1
   41:  invokevirtual   #9; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   44:  return

对照程序可以更好的理解反编译命令,留作以后参考。

可以看到:jvm对于String+String操作符做了优化,通过StringBuilder.append方法来执行+操作,缺点如上所示,在循环执行+操作时,每次都会创建一个新的StringBuilder。

你可能感兴趣的:(javap)