字符串连接:concat()vs" +"操作者 [英] String concatenation: concat() vs "+" operator

查看:108
本文介绍了字符串连接:concat()vs" +"操作者的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设字符串a和b:

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

引擎盖下,它们是一样的吗?



<这是concat反编译作为参考。我希望能够反编译 + 运算符以查看它的作用。

  public String concat(String s){

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


解决方案

否,不完全。



首先,语义略有不同。如果 a null ,那么 a.concat(b)抛出 NullPointerException a + = b 会将的原始值视为好像它是 null 。此外, concat()方法只接受 String 值,而 + 运算符将静默地将参数转换为String(对象使用 toString()方法)。所以 concat()方法在它接受的内容方面更为严格。



要深入了解,请写一个简单类 a + = b;

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

现在用 javap反汇编 - c (包含在Sun JDK中)。你应该看到一个列表,包括:

  java.lang.String cat(java.lang.String,java.lang.String) ; 
代码:
0:新#2; // class java / lang / StringBuilder
3:dup
4:invokespecial#3; //方法java / lang / StringBuilder。< init>:()V
7:aload_1
8:invokevirtual#4; //方法java / lang / StringBuilder.append:(Ljava / lang / String;)Ljava / lang / StringBuilder;
11:aload_2
12:invokevirtual#4; //方法java / lang / StringBuilder.append:(Ljava / lang / String;)Ljava / lang / StringBuilder;
15:invokevirtual#5; //方法java / lang / StringBuilder.toString :()Ljava / lang / String;
18:astore_1
19:aload_1
20:aturn

所以, a + = b 相当于

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

concat 方法应该更快。但是,使用更多字符串时, StringBuilder 方法至少在性能方面获胜。



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



更新正如Pawel Adamski所说,最近的HotSpot中的性能发生了变化。 javac 仍然生成完全相同的代码,但字节码编译器作弊。简单的测试完全失败,因为整个代码都被抛弃了。求和 System.identityHashCode (不是 String.hashCode )显示 StringBuffer 代码有一点点优势。在下次更新发布时,或者您使用其他JVM时,可能会发生更改。来自 @lukaseder HotSpot JVM内在函数列表


Assuming String a and b:

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

Under the hood, are they the same thing?

Here is concat decompiled as reference. I'd like to be able to decompile the + operator as well to see what that does.

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);
    }
}

解决方案

No, not quite.

Firstly, there's a slight difference in semantics. If a is null, then a.concat(b) throws a NullPointerException but a+=b will treat the original value of a as if it were null. Furthermore, the concat() method only accepts String values while the + operator will silently convert the argument to a String (using the toString() method for objects). So the concat() method is more strict in what it accepts.

To look under the hood, write a simple class with a += b;

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

Now disassemble with javap -c (included in the Sun JDK). You should see a listing including:

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

So, a += b is the equivalent of

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

The concat method should be faster. However, with more strings the StringBuilder method wins, at least in terms of performance.

The source code of String and StringBuilder (and its package-private base class) is available in src.zip of the Sun JDK. You can see that you are building up a char array (resizing as necessary) and then throwing it away when you create the final String. In practice memory allocation is surprisingly fast.

Update: As Pawel Adamski notes, performance has changed in more recent HotSpot. javac still produces exactly the same code, but the bytecode compiler cheats. Simple testing entirely fails because the entire body of code is thrown away. Summing System.identityHashCode (not String.hashCode) shows the StringBuffer code has a slight advantage. Subject to change when the next update is released, or if you use a different JVM. From @lukaseder, a list of HotSpot JVM intrinsics.

这篇关于字符串连接:concat()vs&quot; +&quot;操作者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆