当Java编译器将一个原语自动装箱到包装类时,它会在幕后生成什么代码?我想它叫:
答案 0 :(得分:45)
您可以使用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
。没有别的,真的 - 这只是语法糖。
答案 1 :(得分:9)
我想出了一个单元测试,证明调用了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);
}
}
答案 2 :(得分:4)
如果您查找Integer#valueOf(int)的API文档,您会看到它已添加到JDK 1.5中。所有包装器类型(尚未包含它们)都添加了类似的方法来支持自动装箱。对于某些类型,还有一个附加要求,如JLS中所述:
如果框中的值 p 为
true
,false
,byte
,char
范围为\u0000
至\u007f
,或int
与short
之间的-128
或127
号码,然后让 r1 和 r2 < / em>是 p 的任意两次装箱转换的结果。 r1 == r2 的情况总是如此。 §5.1.7
值得注意的是long
s不受相同要求的约束,尽管-128..127
范围内的Long值缓存在Sun的实现中,就像其他整数类型一样。
我还发现,在我的The Java Programming Language副本中,它表示从char
到\u0000
的{{1}}值被缓存,但当然是每个规范的上限是\u00ff
(在这种情况下,Sun JDK符合规范)。
答案 3 :(得分:1)
我建议使用jad之类的内容并对代码进行反编译。你可以学到很多关于java实际做的事情。