コンパイラはオートボクシング用にどのコードを生成しますか?
-
03-07-2019 - |
質問
Javaコンパイラがプリミティブをラッパークラスに自動ボックス化するとき、背後でどのコードが生成されますか?私はそれが呼び出すと想像します:
- ラッパーのvalueOf()メソッド
- ラッパーのコンストラクター
- その他の魔法?
解決
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()
を呼び出し、オートボックス化は指定された Integer で
intValue()
を呼び出しますcode>オブジェクト。本当に他に何もありません-それはただの構文糖です。
他のヒント
ラッパーのコンストラクターの代わりに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)、JDK 1.5で追加されたことがわかります。すべてのラッパータイプ(まだ持っていなかった)には、オートボクシングをサポートするために同様のメソッドが追加されていました。 JLSで説明されているように、特定のタイプには追加の要件があります:
ボックス化される値 p が
true
、false
、byte
、charの場合
、または\ u0000
から\ u007f
の範囲のint
またはshort
の> -128
および127
、次に r1 および r2 を p <の2つのボクシング変換の結果とします/ em>。常に r1 == r2 になります。 &#167; 5.1.7
-128..127
の範囲のLong値はSunの実装にキャッシュされますが、 long
は同じ要件の対象ではないことに注意してください。他の積分型と同じです。
また、のコピーでも発見しましたJavaプログラミング言語では、 \ u0000
から \ u00ff
までの char
値がキャッシュされますが、もちろん上限は仕様は \ u007f
です(この場合、Sun JDKは仕様に準拠しています)。
jad のようなものを入手し、コードを多く逆コンパイルすることをお勧めします。 javaが実際に何をしているのかについてかなり学ぶことができます。