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

标签 java string concatenation

假设字符串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值,而 +运算符将默默地将参数转换为字符串(使用对象的 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方法获胜,至少在性能方面。

String的源代码和StringBuilder (及其包私有(private)基类)可在 Sun JDK 的 src.zip 中找到。您可以看到您正在构建一个 char 数组(根据需要调整大小),然后在创建最终的 String 时将其丢弃。 。实际上,内存分配速度快得惊人。

更新: 正如 Pawel Adamski 指出的那样,最近的 HotSpot 的性能发生了变化。 javac仍然生成完全相同的代码,但字节码编译器会作弊。简单的测试完全失败,因为整个代码都被丢弃了。求和System.identityHashCode (不是 String.hashCode )显示 StringBuffer代码有一点优势。当下一个更新发布时,或者如果您使用不同的 JVM,可能会发生变化。来自 @lukaseder , a list of HotSpot JVM intrinsics .

关于java - 字符串连接: concat() vs "+" operator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55968018/

相关文章:

java - Android套接字客户端未从服务器接收

java - Gradle 将依赖项下载到缓存中而不是 Maven 存储库中

java - Selenium Java Webdriver : Adding a string to an Xpath

C++ vector 迭代 : const vs. const auto 与 no const

ruby - 仅检查要评估的字符串的语法,而不是在 Ruby 中评估

javascript concat() ,想要连接 5 个不同的字符串值

java - 如何配置jackson属性命名策略?

java - string类的哪些对象是final的,是否有任何对象是final的

mysql - MySQL 中 INSERT INTO 和 LOAD DATA from CSV 的区别

MYSQL 连接时的情况