web001 发表于 2013-2-3 11:27:03

「译」在java中,字符串的加法是如何实现的?

 
原文:How is + implemented in Java?
译文:在java中,字符串的加法是如何实现的?
 
当我查看String类的concat函数的源码时,发现字符串连接是这么实现的:
public String concat(String str) {    int otherLen = str.length();    if (otherLen == 0) {      return this;    }    int len = value.length;    char buf[] = Arrays.copyOf(value, len + otherLen);    str.getChars(buf, len);    return new String(buf, true);}那么,字符串的连接符(+)的实现和这个有什么区别呢?如果有区别的话,那它是如何实现的呢?
此外,这两者分别在什么场合使用,有没有性能上的差异。
 
为了回答这个问题,我们可以做一个测试。
首先,我们连接两个字符串
String s1 = "foo";String s2 = "bar";String s3 = s1 + s2;下面我们将这个代码编译成class文件,然后再反编译(可以用JAD),我们得到反编译后的代码是:
String s = "foo";String s1 = "bar";String s2 = (new StringBuilder()).append(s).append(s1).toString();所以,+ 和 concat 肯定是有区别的。
在性能上,从 concat() 源码可以看出,StringBuilder创建了更多的对象,而concat却没有,它使用的String类的内部实现。
 
综上,当我们需要连接两个字符串的时候,我们应当优先考虑使用 concat() 函数,当我们需要连接字符串和其它类型的变量时,再考虑使用+运算符。
 
译者注:用 javap -c 查看java生成的字节码:
java.lang.String cat(java.lang.String, java.lang.String);Code:   0:   new   #2; //class java/lang/StringBuilder   3:   dup   4:   invokespecial   #3; //Method java/lang/StringBuilder."<init>":()V   7:   aload_1   8:   invokevirtual   #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;   11:aload_2   12:invokevirtual   #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;   15:invokevirtual   #5; //Method java/lang/StringBuilder.toString:()Ljava/lang/    String;   18:astore_1   19:aload_1   20:areturn可以看出 a += b 其实等价于
<div style="font-size: 14px; line-height: 21px;">a = new StringBuilder()    .append(a)    .append(b)    .toString();
页: [1]
查看完整版本: 「译」在java中,字符串的加法是如何实现的?