当 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()
,自动拆箱调用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 中所述,对于某些类型有额外的要求:
If the value p being boxed is
true
,false
, abyte
, achar
in the range\u0000
to\u007f
, or anint
orshort
number between-128
and127
, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2. §5.1.7
It's interesting to note that long
s aren't subject to the same requirement, although Long values in the -128..127
range are cached in Sun's implementation, just like the other integral types.
I also just discovered that in my copy of The Java Programming Language, it says char
values from \u0000
to \u00ff
are cached, but of course the upper limit per the spec is \u007f
(and the Sun JDK conforms to the spec in this case).
我建议您大量使用jad和反编译代码。你可以学到很多关于 java 实际在做什么的知识。