Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Method overloading with variable argument

I think this would be a stupid question a little bit, but I can not sure why it is.

code;

public class OverloadingTest {
    public static int sum(int ...a){
        int sum=0;
        for(int i : a){
            sum += i;
        }
        System.out.print("this is variant args//");
        return sum;
    }

    public static double sum(double a, double b) {
        return a + b;
    }

    public static void main(String[] args) {
        System.out.println(sum(1.5, 2.5));
        System.out.println(sum(10, 20));
        System.out.println(sum(10, 20,30));
    }
}

results I expected;

4.0
this is variant args//30
this is variant args//60

actual results in console:

4.0
30.0
this is variant args//60

I can not sure why results of sum(10, 20) 30.0, not 30 of variable argument.

like image 393
rappot Avatar asked Dec 07 '22 02:12

rappot


2 Answers

This is because the compiler always makes the choice to use the most specific method.

Since your second invocation has two arguments, and an int can be converted to a double without loss of precision (see JLS, section 5.1.2), the compiler elects to call your two-argument method.

An IDE will warn you here about the implicit int to double conversion.


edit: as @OlegEterkhin mentions in comments, see JLS, section 15.2.2 for the process used by the compiler to select which method will be used.

And no, this won't work:

int x = sum(10, 20);
like image 55
fge Avatar answered Dec 08 '22 15:12

fge


The answer is in JLS section 15.12.2. Basically, the compiler tries to find any applicable method without having to expand varargs, only using varargs if it has to:

The remainder of the process is split into three phases, to ensure compatibility with versions of the Java programming language prior to Java SE 5.0. The phases are:

  • 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. [...]

  • 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. [...]

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

In this case, the first phase does find a match, as sum(double, double) is applicable for the call sum(10, 20) due to the implicit conversion from int to double.

like image 21
Jon Skeet Avatar answered Dec 08 '22 14:12

Jon Skeet