编译器为自动装箱生成了什么代码?

时间:2009-01-03 05:32:02

标签: java autoboxing

当Java编译器将一个原语自动装箱到包装类时,它会在幕后生成什么代码?我想它叫:

  • 包装器上的valueOf()方法
  • 包装器的构造函数
  • 其他一些魔法?

4 个答案:

答案 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 truefalsebytechar范围为\u0000\u007f,或intshort之间的-128127号码,然后让 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实际做的事情。