文字列の連結: concat() と "+" 演算子 質問する

文字列の連結: concat() と

文字列 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);
    }
}

ベストアンサー1

いいえ、そうではありません。

まず、セマンティクスに若干の違いがあります。aがの場合nulla.concat(b)は をスローしますNullPointerExceptionが、の元の値はであるかのようにa+=b扱われます。さらに、メソッドは値のみを受け入れますが、演算子は引数を暗黙的に文字列に変換します (オブジェクトの メソッドを使用)。そのため、メソッドは受け入れるものに関してより厳密です。anullconcat()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(およびそのパッケージ プライベート基本クラス) は、Sun JDK の src.zip で入手できます。char 配列を構築し (必要に応じてサイズを変更)、最終的な を作成するときにそれを破棄していることがわかりますString。実際には、メモリ割り当ては驚くほど高速です。

更新: Pawel Adamski が指摘しているように、最近の HotSpot ではパフォーマンスが変化しています。 はjavac依然としてまったく同じコードを生成しますが、バイトコード コンパイラが不正行為をします。コード全体が破棄されるため、単純なテストは完全に失敗します。System.identityHashCode( ではなくString.hashCode) を合計すると、コードがわずかに有利であることがわかりますStringBuffer。次の更新がリリースされたとき、または別の JVM を使用したときに変更される可能性があります。翻訳:HotSpot JVM 組み込み関数のリスト

おすすめ記事