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
}
When compiling a method call, the compiler searches for a matching method in this order:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With