budairenqin 发表于 2013-2-3 13:33:08

关于java中字符串连接使用 Stirng+String+... 效率的一点想法

记得自己还是个连菜鸟都算不上的coder的时候,老鸟们总教育我:代码里不要出现String+String+...这种代码,非多线程的情况下要用StringBuilder效率才高
当时没啥感觉,最近闲来无事,想看看java编译器都对String+String+...这种代码怎么处理的呢?于是发现javac也是用StringBuilder来处理的,所以我感觉这两者效率上是没有区别的,如本人理解有错,望老鸟给予指正...
请看代码吧,主要代码我都加上了注释
package test;public class Test {    public static void main(String[] args) {      String s1 = new String("小菜鸟");      String s2 = new String("大菜鸟");                String resultString = s1 + s2 + "老鸟";    }}

以上代码编译成class文件后
用javap Test -verbose 命令看下字节码文件中的内容:
注意下面代码第100行,重点所在
D:\Workspace\MyEclipse\workspace\Test\bin\test>javap Test -verboseCompiled from "Test.java"public class test.Test extends java.lang.ObjectSourceFile: "Test.java"minor version: 0major version: 50Constant pool:const #1 = class      #2;   //test/Testconst #2 = Asciz      test/Test;const #3 = class      #4;   //java/lang/Objectconst #4 = Asciz      java/lang/Object;const #5 = Asciz      <init>;const #6 = Asciz      ()V;const #7 = Asciz      Code;const #8 = Method       #3.#9;//java/lang/Object."<init>":()Vconst #9 = NameAndType#5:#6;//"<init>":()Vconst #10 = Asciz       LineNumberTable;const #11 = Asciz       LocalVariableTable;const #12 = Asciz       this;const #13 = Asciz       Ltest/Test;;const #14 = Asciz       main;const #15 = Asciz       ();Code:   Stack=3, Locals=4, Args_size=1   0:   new   #16; //class java/lang/String |我加上的:创建一个新对象,对象类型存储在常量池#16   3:   dup//我加上的:复制栈顶部一个字长的内容   4:   ldc   #18; //String 小菜鸟 |我加上的:把常量池中索引为#18的值压入栈   6:   invokespecial   #20; //Method java/lang/String."<init>":(Ljava/lang/String;)V |我加上的:调用初始化方法   9:   astore_1//我加上的:将引用类型存入局部变量1   10:new   #16; //class java/lang/String |我加上的:10-19同上实例化另一个String对象(大菜鸟)   13:dup   14:ldc   #23; //String 大菜鸟   16:invokespecial   #20; //Method java/lang/String."<init>":(Ljava/lang/String;)V   19:astore_2   20:new   #25; //class java/lang/StringBuilder |我加上的:创建一个StringBuilder对象   23:dup   24:aload_1//我加上的:从局部变量1中装载引用类型   25:invokestatic    #27; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;   28:invokespecial   #31; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V   31:aload_2//我加上的:从局部变量2中装载引用类型   //哈哈,看到这里了吧,javac(我的jdk版本是1.6)编译后的字节码对于String+String+...的处理也是使用StringBuilder的append的   32:invokevirtual   #32; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;   35:ldc   #36; //String 老鸟   //同理,连接字符串“老鸟”   37:invokevirtual   #32; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;   40:invokevirtual   #38; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;   43:astore_3   44:returnLineNumberTable:   line 7: 0   line 8: 10   line 10: 20   line 11: 44LocalVariableTable:   StartLengthSlotName   Signature   0      45      0    args       [Ljava/lang/String;   10      35      1    s1       Ljava/lang/String;   20      25      2    s2       Ljava/lang/String;   44      1      3    resultString       Ljava/lang/String;}D:\Workspace\MyEclipse\workspace\Test\bin\test>
页: [1]
查看完整版本: 关于java中字符串连接使用 Stirng+String+... 效率的一点想法