重载函数int ...和long ...同时

时间:2012-11-23 06:34:34

标签: java overloading

我想创建两个函数,比如说

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

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

除重命名外是否有解决方法?

4 个答案:

答案 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[],而是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;
    }
}

答案 1 :(得分:1)

问题在于,当您使用方法的<{1}}, 提供完全匹配时调用这些方法,就像您使用的那样integer 即可。此外,var-args可以将逗号分隔的var-args值作为参数。因此int错误。

当您调用重载方法时,ambiguous method首先选择Compiler。然后exact match施放。

现在,由于nearest type只是var-args,编译器无法决定在传递array值时使用哪个数组。因为,这两个数组都不能被视为integerexact 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))