32

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

  • 包装器上的 valueOf() 方法
  • 包装器的构造函数
  • 还有什么魔法?
4

4 回答 4

47

您可以使用该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对象。真的没有别的了——它只是语法糖。

于 2009-01-03T05:40:09.367 回答
10

我想出了一个单元测试,证明调用 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);
    }
}
于 2009-01-04T07:21:31.690 回答
4

如果您查找Integer#valueOf(int)的 API 文档,您会看到它是在 JDK 1.5 中添加的。所有包装器类型(还没有)都添加了类似的方法来支持自动装箱。如 JLS 中所述,对于某些类型有额外的要求:

If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, 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 longs 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).

于 2009-01-04T08:44:26.390 回答
1

我建议您大量使用jad和反编译代码。你可以学到很多关于 java 实际在做什么的知识。

于 2009-01-03T06:03:13.593 回答