Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java: reference to .. is ambiguous, both method method1 and method2 in ... match [duplicate]

I faced with same code:

    public class Devk{
        public static void tMeth(Integer... i){
          System.out.print("A");
        }
        public static void tMeth(int... i){
          System.out.print("B");
        }
        public static void main(String args[]){
          tMeth(Integer.valueOf("7"));//compile error
          tMeth(new int[2]); //returns B
          tMeth(new Integer[2]); //returns A
        }

  }

after invokation I see

java: reference to tMeth is ambiguous, both method tMeth(java.lang.Integer...) in GenericsTest.Test1 and method tMeth(int...) in GenericsTest.Test1 match

method Integer.valueOf("7") returns Integer wrapper. I expect to see A in console.

Who can explain this behaviour and provide general rule for this ?

P.S.

public static void tMeth(Integer i){
    System.out.print("A");
}
public static void tMeth(int i){
    System.out.print("B");
}
public static void main(String args[]){
    tMeth(1); //returns B
    tMeth(new Integer(1)); //returns A
}
like image 955
gstackoverflow Avatar asked Oct 21 '22 13:10

gstackoverflow


1 Answers

When compiling a method call, the compiler searches for a matching method in this order:

  1. Try to find a method without autoboxing/unboxing or varargs.
  2. If no method is found, see if a method matches using autoboxing/unboxing.
  3. If still no method is found, see if a method matches using both varargs and autoboxing/unboxing.

In your case, you are in step (3) here. Since unboxing is allowed, both methods are applicable.

The compiler then tries to find the one that is most specific. One method is more specific than another if its parameter types are all equally or more specific (for example, String is more specific than Object, and int is more specific than long).

But between int and Integer, neither is more specific; the compiler relies on testing (1) before (2) above to get the correct method in the case of, say, foo(int) and foo(Integer).

So, there are two applicable methods and neither is more specific, hence the ambiguity error.

JLS reference

like image 169
Russell Zahniser Avatar answered Oct 23 '22 03:10

Russell Zahniser