String を int などのプリミティブと連結すると、最初に値が自動ボックス化されますか。
元。
String string = "Four" + 4;
どのように値をJavaの文字列に変換しますか?
String を int などのプリミティブと連結すると、最初に値が自動ボックス化されますか。
元。
String string = "Four" + 4;
どのように値をJavaの文字列に変換しますか?
javap -c
Java コンパイラが生成するものを確認するには、生成された実際のバイトコードを表示するために使用すると便利です。
たとえば、次の Java コード:
String s1 = "Four" + 4;
int i = 4;
String s2 = "Four" + i;
次のバイトコードが生成されます。
0: ldc #2; //String Four4
2: astore_1
3: iconst_4
4: istore_2
5: new #3; //class java/lang/StringBuilder
8: dup
9: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V
12: ldc #5; //String Four
14: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/
String;)Ljava/lang/StringBuilder;
17: iload_2
18: invokevirtual #7; //Method java/lang/StringBuilder.append:(I)Ljava/lan
g/StringBuilder;
21: invokevirtual #8; //Method java/lang/StringBuilder.toString:()Ljava/la
ng/String;
24: astore_3
25: return
このことから、次のことがわかります。
"Four" + 4
、Java コンパイラ (私は JDK 6 を使用していました) は、これが定数であると推測するのに十分賢いので、コンパイル時に文字列が連結されるため、実行時の計算作業はありません。"Four" + i
、同等のコードはnew StringBuilder().append("Four").append(i).toString()
Java コンパイラは実際に1を作成し、メソッドを呼び出します。それはバイトコードで見ることができます:StringBuilder
append()
22 invokespecial java.lang.StringBuilder(java.lang.String) [40]
...
29 invokevirtual java.lang.StringBuilder.append(int) : java.lang.StringBuilder [47]
32 invokevirtual java.lang.StringBuilder.toString() : java.lang.String [51]
toString()
それにもかかわらず、動作はボックス化してから:を呼び出すのと同じです"Four" + new Integer(4).toString()
- これは、言語設計者が念頭に置いていたことだと思います。
(1) 正確には、コンパイラはすでに文字列リテラルと int リテラルを単一の文字列リテラルに連結しています"Four4"
。バイトコードの次の行のバイトコードで確認できます。
0 ldc <String "Four4"> [19]
http://jcp.org/aboutJava/communityprocess/jsr/tiger/autoboxing.htmlによると、参照型 (この場合は Integer クラスなど) が必要な場合はいつでも、プリミティブ型でオートボクシングが行われます。
したがって、int は Integer に変換され、その整数オブジェクトの toString() メソッドが呼び出され、その結果が前の文字列に追加されます。