【问题标题】:Does wrapper widening beat unboxing?包装器加宽是否优于拆箱?
【发布时间】:2012-01-31 21:35:55
【问题描述】:
class Dec26 {
    public static void main(String[] args) {
        short a1 = 6;
    new Dec26().go(a1);
    new Dec26().go(new Integer(7));
 }
 void go(Short x) { System.out.print("S "); }
 void go(Long x) { System.out.print("L "); }
 void go(int x) { System.out.print("i "); }
 void go(Number n) { System.out.print("N "); }
 }

输出:

i N

在上面的例子中,为什么编译器选择加宽选项(即 Integer --> Number)而不是拆箱 Integer 并选择 int 选项?

谢谢

【问题讨论】:

  • 正如指定的那样,它确实延迟了 NPE,这是一件好事/坏事。

标签: java oop wrapper scjp


【解决方案1】:

我认为对象优先于原始类型。

【讨论】:

  • 我在某处读到原始类型具有优先权,因为没有破坏 Java 5 之前的代码。
  • @ziggy 在谈到语言语义时不要读“某处” :) 始终使用 JLS — 这可能会很痛苦,但它是唯一合适的来源。
【解决方案2】:

您的问题一般不是关于转换的优先级,而是关于重载解析算法的细节。

出于向后兼容的原因,重载解决过程包括 3 个阶段:

  • 第 1 阶段:识别可通过子类型应用的匹配 Arity 方法
    • 忽略可变参数和装箱/拆箱
  • 第 2 阶段:识别可通过方法调用转换应用的匹配 Arity 方法
    • 忽略可变参数,但尊重装箱/拆箱
  • 第 3 阶段:确定适用的变量 Arity 方法
    • 支持所有可能的转换

如果编译器在一个阶段未能识别出可能适用的方法,它会进入下一个阶段,过度分析可能适用的方法以选择最具体的方法并将其用于调用。

如您所见,在您的情况下,两个调用都可以通过子类型来应用(shortint 的子类型,IntegerNumber 的子类型),因此它们在第 1 阶段得到解决,所以重载解决过程永远不会到达阶段 2,并且可能的拆箱被忽略。

另请参阅:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-25
    • 2012-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多