题
当 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);
}
}
如果您查找 API 文档 整数#valueOf(int), ,你会看到它是在 JDK 1.5 中添加的。所有包装器类型(尚未拥有它们)都添加了类似的方法来支持自动装箱。对于某些类型,还有附加要求,如 JLS 中所述:
如果值 p 被装箱是
true
,false
, , Abyte
, , Achar
在范围中\u0000
到\u007f
, ,或一个int
或者short
之间的数量-128
和127
, ,然后让 r1 和 r2 是任意两个拳击转换的结果 p. 。情况总是如此 r1 == r2. §5.1.7
有趣的是,注意到 long
s 不受相同要求的约束,尽管 Long 值在 -128..127
范围在 Sun 的实现中被缓存,就像其他整数类型一样。
我也刚刚发现在我的副本中 Java 编程语言, , 它说 char
值来自 \u0000
到 \u00ff
被缓存,但当然每个规范的上限是 \u007f
(Sun JDK 符合本例中的规范)。
我建议得到类似的东西 贾德 并大量反编译代码。您可以了解很多有关 java 实际用途的信息。
不隶属于 StackOverflow