Consider the following two sets of methods. The first one is accepted, the second one is rejected as ambiguous. The only difference is between using int and Integer.
Is there a particular need to reject the second one? That would imply that accepting it after boxing (which would lead to the first set) has a problem. What do I miss here?
From my point of view, the Java compiler is too restrictve here.
Set 1:
public void test(Object... values) {}
public void test(Integer x, Object... values) {} // difference here
public void b() {
test(1, "y"); // accepted
}
Set 2:
public void test(Object... values) {}
public void test(int x, Object... values) {} // difference here
public void b() {
test(1, "y"); // marked as ambiguous
}
Set 2 produces the compiler error:
error: reference to test is ambiguous
test(1, "y"); // marked as ambiguous
^
both method test(Object...) in T and method test(int,Object...) in T match
Java 1.8, Eclipse Oxygen
What the compiler doing is implementing the rules set out in JLS 15.12.2.5 for choosing the most specific method in the cases where multiple methods are applicable for the invocation. In the examples in your question, the difference is covered by this line in the spec:
A type
S
is more specific than a typeT
for any expression ifS <: T
(§4.10).
where S <: T
means that S
is a subtype of T
.
In example #1:
Integer
is a subtype of Object
, so it is more specific.In example #2:
int
is not a subtype of Object
or vice versa, so neither type is more specific than the other. The difference is that in the first case, the 1
argument needs to be boxed into Integer, and then the most fitting method chosen; that being the (Integer, Object...)
version.
In the second case, there are two options - boxing or not. This is what makes it ambiguous.
I agree that this is counter-intuitive.
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