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

发布于 2024-07-10 21:37:42 字数 128 浏览 7 评论 0原文

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

  • 包装器上的 valueOf() 方法
  • 包装器的构造函数
  • 还有其他魔法吗?

When the Java compiler autoboxes a primitive to the wrapper class, what code does it generate behind the scenes? I imagine it calls:

  • The valueOf() method on the wrapper
  • The wrapper's constructor
  • Some other magic?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

苦行僧 2024-07-17 21:37:42

您可以使用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() code> 给定的 Integer 对象。 真的没有别的了——这只是语法糖。

You can use the javap tool to see for yourself. Compile the following code:

public class AutoboxingTest
{
    public static void main(String []args)
    {
        Integer a = 3;
        int b = a;
    }
}

To compile and disassemble:

javac AutoboxingTest.java
javap -c AutoboxingTest

The output is:

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

}

Thus, as you can see, autoboxing invokes the static method Integer.valueOf(), and autounboxing invokes intValue() on the given Integer object. There's nothing else, really - it's just syntactic sugar.

把回忆走一遍 2024-07-17 21:37:42

我想出了一个单元测试来证明调用了 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);
    }
}

I came up with a unit test that proves that Integer.valueOf() is called instead of the wrapper's constructor.

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);
    }
}
憧憬巴黎街头的黎明 2024-07-17 21:37:42

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

如果装箱的值ptruefalsebytechar \u0000\u007f 范围内的,或者 intshort 之间的数字>-128 和 127,然后令 r1r2p< 的任意两个装箱转换的结果/em>. 情况总是如此:r1 == r2§5.1.7


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

我还刚刚在我的 Java 编程的副本中发现Language,它说从 \u0000\u00ffchar 值被缓存,但当然每个规范的上限是\u007f (Sun JDK 符合本例中的规范)。

If you look up the API doc for Integer#valueOf(int), you'll see it was added in JDK 1.5. All the wrapper types (that didn't already have them) had similar methods added to support autoboxing. For certain types there is an additional requirement, as described in the 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).

徒留西风 2024-07-17 21:37:42

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

I'd recommend getting something like jad and decompiling code a lot. You can learn quite a bit about what java's actually doing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文