Java 7使用varargs重载

时间:2013-02-05 13:29:28

标签: java overloading variadic-functions

  

可能重复:
  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);
    }
}

还会出现编译时错误。当我们使用varargs重载时,机制是什么?这是一个重载varargs方法的错误吗?

2 个答案:

答案 0 :(得分:16)

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

  • 首先尝试查找不使用装箱/拆箱或varargs的方法
  • 第二次试图找到一个方法,允许装箱/拆箱,但没有varargs
  • 第三次允许拳击,拆箱和varargs

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

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

在你的情况下:

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

修改

我以为你说你的第一个例子编译而不是第二个例子(这是预期的行为)。你似乎在说这两个都没有编译,在这种情况下,它可能是由于你的javac版本中的一个错误,它已经用Java 7修复了。请参阅release notes中的详细信息,“大多数特定Varargs方法选择的变化“。

答案 1 :(得分:0)

由于您已在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);
}

}