Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why an int... variable wrapped into long when both methods present in the same class

Tags:

java

The code below generates the output:In long. If I change the parameter from (int...x) to (int x), it will print It is int instead. Why is that?

public class Sub  {

    void probe(int...x){
        System.out.println("It is int");
    }


    void probe(long x){
        System.out.println("In long");
    }

    public static void main(String[] args){
        int b = 4;
        new Sub().probe(b);
    }
}
like image 871
OPK Avatar asked Jan 16 '15 21:01

OPK


1 Answers

The Java compiler will choose a method first without considering any variable arity methods, i.e. with int.... Only if it doesn't find any matching methods will it consider methods with variable arity. Here, long matches because int can be promoted to long by a widening primitive conversion.

The JLS, Section 15.12.2 governs how the compiler choose a matching method:

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:

  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.

  1. 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.

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

Here, only step 1 is performed, because long matches.

like image 113
rgettman Avatar answered Oct 01 '22 05:10

rgettman