Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ambiguous varargs methods with Object and primitive type

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

like image 999
Ulrich Scholz Avatar asked Sep 04 '17 13:09

Ulrich Scholz


2 Answers

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 type T for any expression if S <: T (§4.10).

where S <: T means that S is a subtype of T.

In example #1:

  • There are two applicable methods
  • The type Integer is a subtype of Object, so it is more specific.
  • Therefore the second method is more specific than the first.
  • Therefore the second method is chosen.

In example #2:

  • There are two applicable methods
  • The type int is not a subtype of Object or vice versa, so neither type is more specific than the other.
  • Therefore the neither method is more specific than the other.
  • Therefore the invocation is ambiguous.
like image 118
Stephen C Avatar answered Oct 17 '22 01:10

Stephen C


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.

like image 37
daniu Avatar answered Oct 17 '22 01:10

daniu