java: reference to .. is ambiguous, both method method1 and method2 in ... match
When compiling a method call, the compiler searches for a matching method in this order:
- Try to find a method without autoboxing/unboxing or varargs.
- If no method is found, see if a method matches using autoboxing/unboxing.
- 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.
gstackoverflow
Updated on June 04, 2022Comments
-
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 seeA
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 about 10 yearsTo 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 about 10 yearsWell, 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 about 10 yearsYes, I see. It makes a difference whether you use arrays or not...So my answer is definitely not complete. I'm sorry... :(
-
gstackoverflow about 10 yearsreally. I have read a lot of information and I don't understand.
-
ucsunil about 10 yearsWhile 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 about 10 years@Luiggi Mendoza share your opinion in answer.
-
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 about 10 yearsOP has demonstrated that this is not true.
-
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 anInteger
. -
gstackoverflow about 10 yearsPlease read my P.S. section. How can you explain it?
-
gstackoverflow about 10 yearsAnswer from there is not clear for me. Possible because my English is so bad
-
Russell Zahniser about 10 yearsHere the matching method is found in phase 1, before autoboxing/unboxing is considered.
-
gstackoverflow about 10 yearsfirst is exact type or covariance?