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

12,817

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

Share:
12,817
gstackoverflow
Author by

gstackoverflow

Updated on June 04, 2022

Comments

  • gstackoverflow
    gstackoverflow almost 2 years

    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
    }
    
  • gstackoverflow
    gstackoverflow about 10 years
    To have public static void tMeth(Integer i) and public static void tMeth(int i) and invoke with int or Integer is valid construction
  • Luiggi Mendoza
    Luiggi Mendoza about 10 years
    Well, the auto boxing is half of the answer. The other half of the answer is related to how the compiler chooses the varargs used in the method.
  • Thomas Uhrig
    Thomas Uhrig about 10 years
    Yes, I see. It makes a difference whether you use arrays or not...So my answer is definitely not complete. I'm sorry... :(
  • gstackoverflow
    gstackoverflow about 10 years
    really. I have read a lot of information and I don't understand.
  • ucsunil
    ucsunil about 10 years
    While the compiler returns a wrapper on valueOf(), it is not smart enough to know whether you intend valueOf() to resolve to an int or a wrapper at run time. When you directly pass in a primitive or a wrapper class, the compiler knows what to expect.
  • gstackoverflow
    gstackoverflow about 10 years
    @Luiggi Mendoza share your opinion in answer.
  • Luiggi Mendoza
    Luiggi Mendoza about 10 years
    @gstackoverflow but this is explained in the duplicate Q/A! Just read the explanation from there! If you find something odd, then edit your question and post it and THAT could make your question not a duplicate.
  • Sotirios Delimanolis
    Sotirios Delimanolis about 10 years
    OP has demonstrated that this is not true.
  • Sotirios Delimanolis
    Sotirios Delimanolis about 10 years
    it is not smart enough to know whether you intend valueOf() to resolve to an int or a wrapper at run time. Of course it is. valueOf() is declared to return an Integer.
  • gstackoverflow
    gstackoverflow about 10 years
    Please read my P.S. section. How can you explain it?
  • gstackoverflow
    gstackoverflow about 10 years
    Answer from there is not clear for me. Possible because my English is so bad
  • Russell Zahniser
    Russell Zahniser about 10 years
    Here the matching method is found in phase 1, before autoboxing/unboxing is considered.
  • gstackoverflow
    gstackoverflow about 10 years
    first is exact type or covariance?