私は文字とJavaで文字列を追加するときに何が起こっているの?

アダム:

私はJavaでこのような何かを行うことができます知っています:

String foo = 'a' + "bee";

私は印刷する場合はfoo、コンソールに私が取得したいですabee何がここで実際にカバーの下に起こっているのでしょうか?私は仮定'a'に推進されているStringが、私はこの種類の変換を支配するもののルールはよく分かりません。これは、ラッパークラスにプリミティブ型からマップをオートボクシングとして、私の知る限りオートボクシングのケースのように思われない(例えばint- > Integer)。されるStringのラッパーと考えますかchar

このもう少し面白くすることの一つは、私が何かをすれば似ていることである String test = 'a' + 'b'; 私は、コンパイルエラーが発生します。私は、彼らは追加しているとき、私のような何かを得るだろうと予想するのが妥当と思われるものの文字は、整数として扱われるため、これがあることを理解"ab"してtest追加する際の挙動を与えられたcharとしますString

ホルガー:

あなたは正確に使用している理由という名前の+文字列の連結のために、オペレータは、歴史的な設計ミスと見ることができます。組み込みの連結演算子を提供することは間違っていないですが、それはプラス演算子ではなかったはずです。

異なる行動についての混乱に加えて、例えばのために'a'+'b'""+'a'+'b'、プラス演算子は、通常可換であることが予想され、つまりはa + b同じ結果を持っているb + a文字列の連結のために保持しません。さらに、演算子の優先順位は驚きにつながることができます。

動作がされ、正確に(JLS§15.18.1)指定します

15.18.1。文字列連結演算子+

唯一のオペランド式のタイプである場合String、文字列変換(§5.1.11は)実行時に文字列を生成するために他のオペランドに対して行われます。

文字列連結の結果への参照であるString2つのオペランド列の連結であるオブジェクト。左側の文字オペランドは右のオペランド新しく作成された文字列の文字の前に。

この定義は、にリンク§5.1.11

5.1.11。文字列の変換

任意のタイプの型に変換することができるStringことにより、文字列変換

値がxプリミティブ型のは、T第一の基準値に変換されるような場合に適切なクラスインスタンス生成式(引数としてそれを与えることによって15.9)。

  • 場合Tboolean、その後、使用new Boolean(x)

  • 場合Tchar、その後、使用new Character(x)

  • 場合Tであるbyteshortまたはint、その後使用new Integer(x)

  • 場合Tlong、その後、使用new Long(x)

  • 場合Tfloat、その後、使用new Float(x)

  • 場合Tdouble、その後、使用new Double(x)

この基準値は、型に変換されたString文字列変換によって。

今だけ基準値を考慮する必要があります。

  • 参照がある場合null、それは文字列「に変換されnull、」(4つのASCII文字null)。

  • そうでなければ、変換は、の呼び出しによってかのように実行されるtoString引数なしで参照されたオブジェクトの方法。呼び出しの結果場合にはtoString方法がありnull、その後、文字列は「null」代わりに使用されます。

(スペックの真の書式設定する「であるnullというよりも」"null"

だから、のふるまいをString foo = 'a' + "bee";すること指定されて、もしあなたが書きましたString foo = new Character('a').toString() + "bee";

しかし§15.18.1引用し続けて:

Stringオブジェクトが新たに(作成され§12.5式が定数式(ある場合を除く)15.28)。

実装が作成した後、中間廃棄を回避するために、1つのステップで変換及び連結を行うことを選択することができるStringオブジェクト。繰り返される文字列連結のパフォーマンスを向上させるために、Javaコンパイラを使用することができるStringBuffer中間体の数低減するクラスまたは類似の技術をString、式の評価によって作成されたオブジェクトを。

プリミティブ型の場合、実装はまた、文字列にプリミティブ型に直接変換することによって、ラッパー・オブジェクトの作成を離れて最適化することができます。

だからあなたの具体的な例について、'a' + "bee"の、実際の行動

String foo = 'a' + "bee";

なります

String foo = "abee";

実行時に任意の追加の操作なしで、それがあるため、コンパイル時の定数

オペランドの1のような、コンパイル時定数ではない場合

char c = 'a';
String foo = c + "bee";

ほとんどの地域で使用されるよう最適化された変異体は、Javaの8(包括的)へのJava 5のすべてのコンパイラでない場合

char c = 'a';
String foo = new StringBuilder().append(c).append("bee").toString();

参照してください、この答えをJavaの9以降では、異なるアプローチが使用されます。

結果の動作は、必ず指定のようになります。

おすすめ

転載: http://10.200.1.11:23101/article/api/json?id=6321&siteId=1