使用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中,两种方法都适用,但
int
比long
更具体,因此选择了vararg(int...)
- 在示例2中,
Integer
与long
没有特殊关系(一个是引用,另一个是初始),因此两者都是最大特定的,并且存在导致编译错误的歧义。
编辑
我以为你说你的第一个例子编译而不是第二个例子(这是预期的行为)。 你似乎在说这两个都没有编译,在这种情况下,它可能是由于你的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); }
}