【问题标题】:Java 7 overloading with varargs [duplicate]使用可变参数重载 Java 7 [重复]
【发布时间】:2013-02-05 13:29:27
【问题描述】:

可能重复:
bug with varargs and overloading?

谁能解释一下这个是如何工作的:

class Vararg {
    static void vararg(int... x) {
        System.out.println("Integer..."); 
    }

    static void vararg(long... x) { 
        System.out.println("long..."); 
    }

    public static void main(String [] args) {
        int s = 0;
        vararg(s,s);
    }
}

获取编译时错误

class Vararg {
    static void vararg(Integer... x) {
        System.out.println("Integer..."); 
    }

    static void vararg(long... x) {
        System.out.println("long..."); 
    }

    public static void main(String [] args) {
        int s = 0;
        vararg(s,s);
    }
}

还会出现编译时错误。当我们使用可变参数重载时的机制是什么?这是重载可变参数方法的错误吗?

【问题讨论】:

  • 方法的运行时参数不明确

标签: java overloading variadic-functions


【解决方案1】:

实质上,确定哪种方法适用,the compiler runs a few steps

  • 首先尝试在不使用装箱/拆箱或可变参数的情况下找到一种方法
  • 第二次尝试找到一种方法,允许装箱/拆箱,但没有可变参数
  • 第三个允许装箱、拆箱和可变参数

在您的情况下,第三步适用于所有方法。

然后编译器确定哪些方法是适用的,以及一个是否比另一个更具体。详细规则在JLS 15.12.2.4。简而言之,它会查看类型并检查一种类型是否比另一种更具体(即,一种类型对于引用来说是另一种的子类,或者对于基元来说,一种类型比另一种类型更窄)。

在你的情况下:

  • 在示例 1 中,两种方法都适用,但 intlong 更具体,因此选择了 vararg(int...)
  • 在示例 2 中,Integerlong 没有 特异性 关系(一个是引用,另一个是原始),因此两者都具有最大的特异性,并且存在歧义导致编译错误。

编辑

我以为您是在说您的第一个示例编译但不是第二个(这是预期的行为)。您似乎是说两者都无法编译,在这种情况下,这可能是由于您的 javac 版本中存在错误,该错误已通过 Java 7 修复。请参阅release notes 中的详细信息,名为“最具体的更改” Varargs 方法选择”。

【解决方案2】:

由于您在 vararg(type... var) 方法中发送了 int 值,并且重载的方法包含一个 Integer 和一个 long 因此,int 值会自动转换为 long 并因此产生歧义。在重载方法中使用不同的参数类型。

class Vararg {
static void vararg(Integer... x) {
    System.out.println("Integer..."); 
}

static void vararg(String... x) {
    System.out.println("String..."); 
}

public static void main(String [] args) {
    int s = 0;
    vararg(s,s);
}

}

【讨论】:

    猜你喜欢
    • 2018-01-09
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多