字符串连接:concat()vs + operator

问题:

假设字符串a和b:

a += b
a = a.concat(b)

在引擎盖下,他们是同一件事吗?
这是concat反编译作为参考。我想要能够反编译+运算符,看看是做什么的。

public String concat(String s) {

    int i = s.length();
    if (i == 0) {
        return this;
    }
    else {
        char ac[] = new char[count + i];
        getChars(0, count, ac, 0);
        s.getChars(0, i, ac, count);
        return new String(0, count + i, ac);
    }
}

回答:

不,不行
首先,语义有一点区别。如果anull,则a.concat(b)将抛出NullPointerException,但a+=b将会将a的原始值视为null。此外,concat()方法仅接受String值,而+运算符将静默地将参数转换为String(对于对象使用toString()方法)。所以concat()方法在接受的方面更加严格。
看下面,写一个简单的类与a += b;

public class Concat {
    String cat(String a, String b) {
        a += b;
        return a;
    }
}

现在使用javap -c(包括在Sun JDK中)进行拆卸。你应该看到一个列表,包括:

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相当于

a = new StringBuilder()
    .append(a)
    .append(b)
    .toString();

concat方法应该更快。然而,使用StringBuilder方法获得更多的字符串,至少在性能方面。
Sun JDK的src.zip中提供了StringStringBuilder(及其包私有基类)的源代码。您可以看到,您正在构建一个字符数组(根据需要调整大小),然后在创建最终String时将其抛弃。在实践中,内存分配令人惊讶的快。
 更新:正如Pawel Adamski所说,在最近的HotSpot中,性能发生了变化。 javac仍然产生完全相同的代码,但字节码编译器作弊。简单的测试完全失败,因为整个代码体被丢弃。总结System.identityHashCode(而不是String.hashCode)显示StringBuffer代码具有轻微的优势。如果下次更新被释放,或者如果您使用其他JVM,则可能会发生更改。从@lukasedera list of HotSpot JVM intrinsics

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: String concatenation: concat() vs + operator

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

− 1 = 5