Java コンパイラがプリミティブをラッパー クラスに自動ボックス化するとき、バックグラウンドで生成されるコードは何ですか? 私はそれが呼び出すと想像します:
- ラッパーの valueOf() メソッド
- ラッパーのコンストラクター
- 他の魔法?
Java コンパイラがプリミティブをラッパー クラスに自動ボックス化するとき、バックグラウンドで生成されるコードは何ですか? 私はそれが呼び出すと想像します:
javap
ツールを使用して、自分の目で確認できます。次のコードをコンパイルします。
public class AutoboxingTest
{
public static void main(String []args)
{
Integer a = 3;
int b = a;
}
}
コンパイルおよび逆アセンブルするには:
javac AutoboxingTest.java
javap -c AutoboxingTest
出力は次のとおりです。
Compiled from "AutoboxingTest.java"
public class AutoboxingTest extends java.lang.Object{
public AutoboxingTest();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_3
1: invokestatic #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
4: astore_1
5: aload_1
6: invokevirtual #3; //Method java/lang/Integer.intValue:()I
9: istore_2
10: return
}
したがって、ご覧のとおり、オートボクシングは静的メソッドを呼び出し、オートアンボックスは指定されたオブジェクトでInteger.valueOf()
呼び出します。他には何もありません - それはただの構文糖衣です。intValue()
Integer
ラッパーのコンストラクターの代わりに Integer.valueOf() が呼び出されることを証明する単体テストを思いつきました。
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import org.junit.Test;
public class Boxing {
@Test
public void boxing() {
assertSame(5, 5);
assertNotSame(1000, 1000);
}
}
Integer#valueOf(int)の API ドキュメントを調べると、JDK 1.5 で追加されたことがわかります。すべてのラッパー タイプ (まだ持っていないもの) には、オートボクシングをサポートするために同様のメソッドが追加されていました。特定のタイプについては、JLS で説明されているように、追加の要件があります。
ボックス化される値pが
true
,false
, abyte
, aから までchar
の範囲の aまたは と の間の数値である場合、r1とr2をpの任意の 2 つのボックス化変換の結果とします。r1 == r2の場合は常にそうです。§5.1.7\u0000
\u007f
int
short
-128
127
他の整数型と同様に long
、範囲内の Long 値は Sun の実装でキャッシュされますが、s は同じ要件の対象ではないことに注意してください。-128..127
また、 The Java Programming Language のコピーで、 からまでのchar
値がキャッシュされると書かれていることも発見しましたが、もちろん、仕様ごとの上限は です(この場合、Sun JDK は仕様に準拠しています)。\u0000
\u00ff
\u007f
jadのようなものを入手してコードを逆コンパイルすることをお勧めします。Java が実際に何をしているのかについて、かなりのことを学ぶことができます。