Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ambiguity error while overloading var args method and wrapper methods in java

I tried to compile following code but got error

static void test(long... x)
{ 
    System.out.println("long..."); 
}

static void test(Integer... x)
{
    System.out.println("Integer..."); 
}

public static void main(String [] args) {
    int no=5;
    test(no,no);//getting error at this  point  in eclipse 'The method test(long[]) is ambiguous '
}

I donot know why it is ambiguous. means if I am passing an int value it should auto-box and test(Integer..x) should get called..on similar line test(long..x ) should be get called..this is my understanding..can someone explain this why it is ambiguous ?

like image 690
sar Avatar asked Sep 30 '22 22:09

sar


People also ask

What is ambiguity in method overloading in Java?

There are ambiguities while using variable arguments in Java. This happens because two methods can definitely be valid enough to be called by data values. Due to this, the compiler doesn't have the knowledge as to which method to call.

What is ambiguous error in Java?

Ambiguity errors occur when erasure causes two seemingly distinct generic declarations to resolve to the same erased type, causing a conflict. Here is an example that involves method overloading.

What is method overloading and when does ambiguous overloading occur?

Method Overloading is a feature that allows a class to have multiple methods with the same name but with different number, sequence or type of parameters. In short multiple methods with same name but with different signatures.


2 Answers

int parameter does not match either of your definitions - one is defined with long and the other with Integer so it is left for the compiler to decide. Cast to long is equally valid as boxing to Integer

http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2

like image 113
Germann Arlington Avatar answered Oct 06 '22 00:10

Germann Arlington


Variable arity comes last in determining the most specific method. The rules to determine which vararg method applies when there are several are defined in JLS 15.12.2.4 - here is an extract:

One variable arity member method named m is more specific than another variable arity member method of the same name if either:

  • [...]
  • One member method has k parameters and the other has n parameters, where n ≥ k, and:

The types of the parameters of the first method are U1, ..., Uk-1, Uk[]. The types of the parameters of the other method are T1, ..., Tn-1, Tn[]. For all j from 1 to n, Uj <: Tj In your case, k = n, and U1[] = int[] and T1[] = long[] so the determination can be made if int <: long or the opposite.

In other words, the type taken into account is not int[] vs. long[] but int vs long. And it happens that int <: long so the int... method should be chosen and it should compile.


Conclusion:

The code should (and does) compile fine with Java 7 but would not compile with Java 5 or 6. The code below prints int with 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;
    }
}
like image 23
Sunny Avatar answered Oct 06 '22 00:10

Sunny