我想创建两个函数,比如说
long min(long...);
int min(int...);
但是当我尝试调用第二个min(1, 5)
时,我得到一个模糊的方法调用
除重命名外是否有解决方法?
答案 0 :(得分:6)
这是一个已知错误
您描述的行为是使用Java 7修复的错误。请参阅release notes中的详细信息,该部分称为“大多数特定Varargs方法选择中的更改”。
它应该编译的原因
变量arity在确定最具体的方法方面是最后的。在JLS 15.12.2.4中定义了多个vararg方法时应用哪些vararg方法的规则 - 这是一个提取:
一个名为m的变量arity成员方法比另一个同名的变量arity成员方法更具体,如果: - [...]
- 一个成员方法有k个参数,另一个有n个参数,其中n≥k,并且:
- 第一种方法的参数类型是U1,...,Uk-1,Uk []。
- 另一种方法的参数类型是T1,...,Tn-1,Tn []。
- 对于从1到n的所有j,Uj<:Tj
在您的情况下,k = n,U1[] = int[]
和T1[] = long[]
因此可以在int <: long
或相反的情况下进行确定。
换句话说,考虑的类型不是int[]
与long[]
,而是int
与long
。它发生在int <: long
,因此应该选择int...
方法并且应该编译。
<强>结论:强>
代码应该(并且确实)可以用Java 7编译,但是不能用Java 5或6编译。下面的代码用Java 7打印int
:
public class Test1 {
public static void main(String[] args) {
new Test1().m(1, 2);
}
int m(int... i) {
System.out.println("int");
return 0;
}
long m(long... i) {
System.out.println("long");
return 0;
}
}
答案 1 :(得分:1)
问题在于,当您使用方法的<{1}},无 提供完全匹配时调用这些方法,就像您使用的那样integer
即可。此外,var-args
可以将逗号分隔的var-args
值作为参数。因此int
错误。
当您调用重载方法时,ambiguous method
首先选择Compiler
。然后exact match
施放。
现在,由于nearest type
只是var-args
,编译器无法决定在传递array
值时使用哪个数组。因为,这两个数组都不能被视为integer
或exact match
。因此,这两种方法都适用于呼叫。
在nearest conversion
的情况下,有关method invocation
的更多规则。您可以从Overloading
了解这些内容。
与@assylias answer中一样,这个问题已在Java 7中得到修复。但它在Java版本中不起作用&lt; 7。
答案 2 :(得分:1)
试试这个
public class Test {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new Test().m(100L,512L);
new Test().m(100,512);
}
int m(int... i) {
System.out.println("int");
return 0;
}
long m(long... i) {
System.out.println("long");
return 0;
}
}
答案 3 :(得分:0)
这些方法签名是唯一的,并且是有效的方法重载。
问题必须出在方法调用参数中。我的猜测是你用文字调用方法,比如:
min(100)
它并不喜欢这样,因为100是一个整数字面值,但它会自动转换为long。
通过在长文字结尾处使用L来消除方法调用的歧义应解决问题:
min(100L)
此外,您可以使用Java Object Integer和Long显式调用,并让autoboxing负责转换为基本类型:
min(new Long(100))
min(new Integer(100))