5

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 ?

Not a bug
  • 4,286
  • 2
  • 40
  • 80
sar
  • 1,277
  • 3
  • 21
  • 48
  • What is the JDK version that you're using? And what happens if you compile it from command line? Please check if you're not bitten by this: http://stackoverflow.com/a/7689819/2231632 – Praba Apr 29 '14 at 12:14

2 Answers2

2

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

Germann Arlington
  • 3,315
  • 2
  • 17
  • 19
2

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;
    }
}
Abimaran Kugathasan
  • 31,165
  • 11
  • 75
  • 105
Sunny
  • 308
  • 2
  • 14
  • What about `m (Integer... i)` which is in OP's question ?? [THAT WILL NOT COMPILE...](http://ideone.com/JTrTYq) and [here is the reason.](http://stackoverflow.com/a/23364636/1686291) – Not a bug Apr 29 '14 at 12:48