2016-03-22 4 views
2

非常に簡単な質問です。パフォーマンスとは関係がありますか?他に何か?文字列を扱うときに単一の文字に "c"または "c"を使用する必要がありますか?

System.out.println('c'); 
System.out.println("c"); 

System.out.println("Letter: " + "c"); 
System.out.println("Letter: " + 'c'); 

+1

あなたの意図に近いものは何ですか?将来のコード読者にはどんなことが明らかになりますか? –

答えて

8

これらは異なるものです。 "c"は長さ1のStringオブジェクトです。 'c'charプリミティブ値(Javaの整数型の1つ)です。

なぜ彼らは互換性があると思われるのかは、文字列連結のJavaのルールのためです。言語ではaString + aCharが、UTF-16の値aCharで表される文字をaStringに追加することで結果として得られる文字列になると定義されています。特定の例では、式はコンパイル時定数Stringの式として扱われ、実行時ではなくコンパイラによって評価されます。これを見るには、コードをコンパイルし、結果のバイトコードを調べます。

Java言語仕様では、何が起こっているのかを説明しています。まず、一つはJLS §15.18.1 ("String Concatenation Operator +")読み込み:

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

文字列連結の結果は、2つのオペランド文字列の連結であるStringオブジェクトへの参照です。

そして§5.1.11において、我々は、(他のルールの間)を見つける:プリミティブ型T

xは、最初に適切なクラスのインスタンスへの引数として与えているかのように基準値に変換されます。生成式(§15.9):

  • ...
  • Tはである場合、次にnew Character(x)を使用します。
  • ...

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

だから、理論的には、char定数'c'Characterオブジェクトへautoboxedです。しかし、実際には、コンパイラとコアクラスはかなりの自由をとり、より効率的な(ただし機能的に同等の)コードを生成します。

+1

文字を文字列に追加するのはStringBuilderで行われ、 ''c' 'をオブジェクトに変換しません。 –

+0

@ TeemuIlmonen - 実際、オートボクシングは理論上**まさに進行中です**。私の拡大された答えを見てください。しかし実際には、オートボクシングも 'StringBuilder'も使用されていません。コンパイラは単に式全体をコンパイル時の文字列定数として扱います。 –

+0

はい、定数を扱う場合、StringBuilderは必要ありません。私は、参照によって、「あたかも「あたかも」のように」と言うときに、どのパスを使用する必要があるかを具体的に記述していないと推測されます。分割するヘア:autoboxingは 'Character(x)'ではなく 'Character.valueOf(x)'でしょうか? –

関連する問題