【问题标题】:Java issue with var-args and boxingvar-args 和装箱的 Java 问题
【发布时间】:2011-10-02 18:56:38
【问题描述】:

我有一个关于以下代码sn-p的问题:

    class VarArgsTricky {
    static void wide_vararg(long... x) {
        System.out.println("long...");
    }

    static void wide_vararg(Integer... x) {
        System.out.println("Integer...");
    }

    public static void main(String[] args) {
        int i = 5;
        wide_vararg(i, i, i); // needs to widen and use var-args
        Long l = 9000000000l;
        wide_vararg(l, l); // prints sucessfully "long..."
    }
}

第一次调用wide_vararg 编译失败(说该方法不明确),而第二次编译正常。

关于这种行为的任何解释? 谢谢!

【问题讨论】:

  • 如果这不仅仅是关于重载的实验,请阅读有效的 Java SE:第 41 条明智地使用重载。
  • 这纯粹是一个实验,只是为了解决 OCPJP 认证考试的潜在问题。

标签: java


【解决方案1】:

第一个wide_vararg 调用不明确,因为编译器可以或者

  • ints 扩大到longs,并调用第一个wide_vararg 方法,
  • ints 自动装箱到Integers,然后调用第二个wide_vararg

它不知道它应该做什么,但是,它拒绝编译模棱两可的方法调用。如果您希望第一次调用编译,请将i 声明为Integerlong,而不是int

【讨论】:

  • 根据 K&B SCJP 6 书扩展击败拳击,而拳击击败 var-args。所以第一次调用应该选择加宽而不是自动装箱。如果 i 被声明为 Integer 它也不会编译。当然,长期有效。问题仍然存在:为什么它不选择扩大而不是自动装箱?
  • 嗯,你是对的。我还不确定为什么。哎呀,这可能是一个编译器错误。不过,可变参数是否会被加宽或装箱打败,这不是问题,因为没有非可变参数的选择。
  • 没有非可变参数的选择,这是真的。它可能是某种编译器错误或一些鲜为人知的功能。确切地知道会很有趣。
【解决方案2】:

当调用 var-arg 方法时,参数会在编译时转换为该类型的数组。

在第一次调用中,参数被转换为 int[]。由于 Java 中的所有数组都是 Object 类的直接子类型,因此原始扩展的概念在这种情况下不适用,因为 long[] 和 Integer[] 处于同一级别,因此两个重载都变得同样适用。因此模棱两可

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-20
    • 2013-07-29
    • 2011-05-29
    • 1970-01-01
    • 2014-12-25
    • 2014-08-17
    • 1970-01-01
    相关资源
    最近更新 更多