我想创建两个函数,比如说
long min(long...);
int min(int...);
但是当我尝试调用第二个 ie 时,min(1, 5)
我得到了模棱两可的方法调用
除了重命名还有其他解决方法吗?
我想创建两个函数,比如说
long min(long...);
int min(int...);
但是当我尝试调用第二个 ie 时,min(1, 5)
我得到了模棱两可的方法调用
除了重命名还有其他解决方法吗?
这是一个已知的错误
您描述的行为是 Java 7 已修复的错误。请参阅发行说明中的详细信息,名为“更改最具体的 Varargs 方法选择”部分。
它应该编译的原因
在确定最具体的方法时,可变参数排在最后。在JLS 15.12.2.4中定义了用于确定当有多个 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[]
vs.long[]
而是int
vs. long
碰巧应该选择int <: long
该int...
方法并且应该编译它。
结论:
该代码应该(并且确实)可以使用 Java 7 编译,但不能使用 Java 5 或 6 编译。下面的代码int
使用 Java 7 打印:
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;
}
}
问题是当您使用 调用这些方法时integer
,没有任何方法提供与您使用的参数完全匹配的参数。此外,两者都可以将用逗号分隔的值作为参数。因此错误。var-args
var-args
int
ambiguous method
当你调用重载方法时,Compiler
选择第exact match
一个。然后nearest type
投。
现在,由于var-args
只是一个array
,编译器在传递值时无法决定使用哪个数组integer
。因为,这两个数组都不能被视为exact match
或nearest conversion
。因此,它需要两种方法都可以调用。
关于. method invocation
_ Overloading
您可以从Java Language Specification
.
正如@assylias 的回答一样,这个问题已在 Java 7 中得到修复。但它不适用于 Java 版本 < 7。
试试这个
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;
}
}
这些方法签名是唯一的,并且是有效的方法重载。
问题必须出在方法调用参数中。我的猜测是您正在使用文字调用该方法,例如:
min(100)
它不喜欢这样,因为 100 是一个整数文字,但它会自动转换为长整数。
通过在长文字末尾使用 L 来消除方法调用的歧义应该可以解决问题:
min(100L)
此外,您可以使用 Java Object Integer 和 Long 来显式调用,并让自动装箱处理到原始类型的转换:
min(new Long(100))
min(new Integer(100))