Javac和Primitives:Boxed vs. Unboxed

时间:2011-05-24 11:52:19

标签: java javac primitive boxing

我的问题是:为什么原始类型必须包装在一个对象中,何时也可以让编译器为你设置正确的东西?

  1. 调用原始值x的方法可以从x.call()转换为X.call(x) - 这是我试图在下面说明的内容。
  2. 泛型不是在运行时保留(对吗?),因此不需要在运行时访问类信息 - 您可以简单地用int替换每个Integer实例,并重写上面的重写方法调用,并以可执行代码结束。
  3. 所以基本上,我问的是:我在这里缺少什么?


    我一直想知道这个问题:为什么Java编译器不能翻译......

    int a = 482;
    int b = 12;
    System.out.println((a + b).toHexString());
    

    ...到以下代码......

    int a = 482;
    int b = 12;
    System.out.prinln(Ints.toHexString(a + b));
    

    ...从而消除了装箱和拆箱的全部需求?

    (因此,编译方法调用(静态)函数调用,并在需要时保留一个Int.class实例 - 例如在调用Ints.getClass(_)之后?)


    为清晰起见添加了评论:

      

    @Adam:不,我不认为这会导致   装箱/拆箱。该示例尝试   来说明基元是如何形成的   被视为语言中的对象,   但作为编译器的原语。   这会删除(轻微)   运行时的开销,令人困惑   语言中的东西。因此   预期的问题正是:为什么   没有极具天赋的编译器   开发人员选择此解决方因为,如果他们没有,那里   我必须是一个明显的不可能性   没有看到。我想知道什么   它是。 - Pepijn

3 个答案:

答案 0 :(得分:3)

我认为你的意思是Integer.toHexString,而不是Ints.toHexString。后者不是java.lang的一部分,编译器无法知道任何有关它的信息。

理论上,如果Java语言指定了这样的翻译,编译器可以将(a + b).toHexString()的调用转换为Integer.toHexString(a + b)。 (例如,将int a自动装箱Integer指定为Integer.valueOf(a)。)

我想Java语言维护者认为这对于Java程序员来说太“神奇”了 - 在所有版本的Java中,原始类型都没有方法或字段。一般来说,Java旨在避免语法糖 - 这就是为什么它通常比大多数其他语言更冗长。

答案 1 :(得分:1)

因此,我们可以将基于原始类型的方法映射到其包装类型的静态方法,很好。

这根本不涉及装箱/拆箱,只是语法糖以另一种方式编写相同的方法调用 - 而且只有极少数的方法,这些方法在包装类中预先定义。

想要将原始值视为对象时,

装箱是必要的,例如:

  • 将其传递给只接受对象的方法
  • 将其放入对象类型
  • 的变量中
  • 从必须返回对象的方法返回

这些特殊(但非常重要)的案例是:

  • 将其放入对象数组
  • 将其放入集合

取消装箱是必要的,如果我们有这样一个盒装基元并想要它的纯形式,例如在调用返回对象的方法或从变量中获取值之后。

在Java 5(或1.5)之前,我们必须通过.valueOf()方法或toXXX()手动完成所有此装箱和拆箱。现在,它会在必要时自动完成(自动装箱)。

答案 2 :(得分:0)

编译器将为

做些什么
List<Integer> list = new ArrayList<Integer>();
list.add(5);
int i = list.get(0);

这里需要一个Integer实例,因此需要装箱/拆箱。