Jayesh
Jayesh

Reputation: 6111

Ambiguous Overloaded method call resolved

When I call, call('a'); it output "char" and it is fine because char primitive type will take first priority over boxing it to Character.

static void call(char i){
    System.out.println("char");
}

static void call(Character i){
    System.out.println("Character");
}

How is call to call('a', 'a'); is ambiguous?

static void call(char i, Character j){
    System.out.println("char");
}

static void call(Character i, Character j){
    System.out.println("Character");
}

What I am thinking is for second parameter compiler has to go for Boxing and for first parameter perfect match is char primitive type, so call to call('a','a'); can be resolved to call(char i, Character j) method.

Obviously I am understanding it wrong, someone please explain this.

Some links where particular this kind of example is explained will be helpful.

Upvotes: 4

Views: 324

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1500675

How is call to call('a', 'a'); is ambiguous?

Because in order for the (char i, Character j) overload to be applicable, the rules around boxing are brought into play - and at that point both calls are applicable. This is the second phase of determining the method signature (JLS 15.12.2):

  1. The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.

  2. The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the third phase.

So in phase 2, both methods are applicable, but the rules for determining the most specific method (JLS 15.12.2.5) don't make either of the calls more specific than each other. It's not a matter of "unboxed is more specific than boxed" - it's a matter of "can I resolve this without any boxing" before "can I resolve this with boxing".

Upvotes: 5

Idos
Idos

Reputation: 15310

The answer is in the JLS 15.12.2 Compile-Time Step 2: Determine Method Signature:

For your first call method with char and Character the compiler needs only the first phase in order to know which method to call. And in the first phase it's not mixing boxed and primitive types:

The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.

However, in your calls with 2 arguments (char and Character, and Character and Character) the compiler needs to get to the second phase trying to distinguish between them, and at that specific point both method are valid:

The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation.

Upvotes: 4

Related Questions