Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the compiler prefer an int overload to a varargs char overload for a char?

Code

public class TestOverload {      public TestOverload(int i){System.out.println("Int");}     public TestOverload(char... c){System.out.println("char");}      public static void main(String[] args) {         new TestOverload('a');         new TestOverload(65);     } } 

Output

Int Int 

Is it expected behaviour? If so, then why? I am expecting: char, Int

Note: I am using Java 8

like image 489
Amit Kumar Gupta Avatar asked Sep 09 '15 05:09

Amit Kumar Gupta


People also ask

Can Varargs method be overloaded?

Also, Varargs methods can be overloaded if required.

What is the benefit of having overloaded methods?

Advantages of method overloading in java Method overloading increases the readability of the program. Overloaded methods give programmers the flexibility to call a similar method for different types of data. Overloading is also used on constructors to create new objects given different amounts of data.

How autoboxing is applied in method overloading?

Autoboxing is the process of converting a primitive value into an object of the corresponding wrapper class is called autoboxing. For example, converting int to Integer class. While Unboxing is a process of converting an object of a wrapper type to its corresponding primitive value is called unboxing.


1 Answers

Methods with varargs (...) have the lowest priority when the compiler determines which overloaded method to choose. Therefore TestOverload(int i) is chosen over TestOverload(char... c) when you call TestOverload with a single char parameter 'a', since a char can be automatically promoted to an int.

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. This guarantees that any calls that were valid in the Java programming language before Java SE 5.0 are not considered ambiguous as the result of the introduction of variable arity methods, implicit boxing and/or unboxing. However, the declaration of a variable arity method (§8.4.1) can change the method chosen for a given method method invocation expression, because a variable arity method is treated as a fixed arity method in the first phase. For example, declaring m(Object...) in a class which already declares m(Object) causes m(Object) to no longer be chosen for some invocation expressions (such as m(null)), as m(Object[]) is more specific.

  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. This ensures that a method is never chosen through variable arity method invocation if it is applicable through fixed arity method invocation.

  3. The third phase (§15.12.2.4) allows overloading to be combined with variable arity methods, boxing, and unboxing.

EDIT:

It you wish to force the compiler to call the TestOverload(char... c) constructor, you can pass to the constructor call a char[] :

new TestOverload (new char[] {'a'}); 
like image 196
Eran Avatar answered Sep 23 '22 16:09

Eran