使用varargs重载Java 7

可能重复:
varargs和重载的错误?

任何人都可以解释我这是如何工作的:

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方法的错误吗?

实质上,要确定哪种方法适用, 编译器会运行几个步骤 :

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

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

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

在你的情况下:

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

编辑

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

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

}