当 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, , A byte, , A char 在范围中 \u0000\u007f, ,或一个 int 或者 short 之间的数量 -128127, ,然后让 r1r2 是任意两个拳击转换的结果 p. 。情况总是如此 r1 == r2. §5.1.7

有趣的是,注意到 longs 不受相同要求的约束,尽管 Long 值在 -128..127 范围在 Sun 的实现中被缓存,就像其他整数类型一样。

我也刚刚发现在我的副本中 Java 编程语言, , 它说 char 值来自 \u0000\u00ff 被缓存,但当然每个规范的上限是 \u007f (Sun JDK 符合本例中的规范)。

我建议得到类似的东西 贾德 并大量反编译代码。您可以了解很多有关 java 实际用途的信息。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top