重载函数int …和long …同时

我想创建两个函数

long min(long...); int min(int...); 

但是当我尝试调用第二个即min(1, 5)我得到了模糊的方法调用

除了重命名之外还有解决方法吗?

这是一个已知的错误

您描述的行为是使用Java 7修复的错误。请参阅发行说明中的详细信息,“最具体的Varargs方法选择中的更改”一节。

它应该编译的原因

变量arity在确定最具体的方法方面是最后的。 在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[]long[]而是intlong 。 并且它发生了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; } } 

问题是当你使用integer调用那些方法时, 没有一个方法提供参数的完全匹配就像你使用var-args 。 此外, var-args都可以将逗号分隔的int值作为参数。 因此ambiguous method错误。

当您调用重载方法时, Compiler选择exact match 。 然后是nearest type

现在,因为var-args只是一个array ,所以编译器在传递integer数值时无法决定使用哪个数组。 因为,两个数组都不能被视为exact matchnearest conversion 。 因此,这两种方法都适用于呼叫。

Overloading情况下,有很多关于method invocation规则。 您可以从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是一个整数字面值,但它会自动转换为long。

通过在长文字结尾处使用L消除方法调用的歧义应解决问题:

 min(100L) 

此外,您可以使用Java Object Integer和Long显式调用,并让autoboxing负责转换为基本类型:

 min(new Long(100)) min(new Integer(100))