Ulrich Scholz
Ulrich Scholz

Reputation: 2111

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

Upvotes: 7

Views: 280

Answers (3)

Ulrich Scholz
Ulrich Scholz

Reputation: 2111

To close this issue, let me summarize actual answers to my question as I understand them: the behaviour is correct according to the specification. The specification could be relaxed such that primitive types are covered as their non-primitive counterparts. One reason that's not done yet is the complexity of specifying and implementing a fast and correct parser.

Upvotes: 0

Stephen C
Stephen C

Reputation: 718886

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.

Upvotes: 5

daniu
daniu

Reputation: 15008

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.

Upvotes: 1

Related Questions