What will be the result of compilation and execution of the following code using JDK7 or newer?

public class Main { 
    public static void var(Integer x, int y) { 
        System.out.println("Integer int"); 
    } 
 
    public static void var(Object... x) { 
        System.out.println("Object"); 
    } 
 
    public static void var(int... x) { 
        System.out.println("int... x"); 
    } 
 
    public static void var(Integer... x) { 
        System.out.println("Integer..."); 
    } 
 
    public static void main(String... args) {  
        byte i = 0; 
        Integer i2 = 127; 
        var(i, i2); 
    } 
}
Explanation

If class does not have a method with parameters of exactly the same types as given arguments, compiler tries to apply the following conversions:

1a. Widening primitive conversions, for example: byte -> int
1b. Widening reference conversions, for example: Integer -> Object

2a. Unboxing conversion (with possible widening primitive conversion), for example: Integer -> int
2b. Boxing conversion (with possible widening reference conversion), for example: byte -> Byte -> Object

It is impossible using the conversions above to convert a couple (byte, Integer) into a couple (Integer, int)
After those conversions compiler tries to use varargs.

In our example it can be done in two different ways:
(byte, Integer) -> ( (1a), (2a) ) -> (int, int) -> (int ...) (byte, Integer) -> ( (2b), (1b) ) -> (Object, Object) -> (Object ...)

In this case JDK6 violates the specification and generates a call to (int ...). In JDK7 this behavior is already fixed and compilation error occurs: "reference to var is ambiguous, both method var(Object...) in Main and method var(int...) in Main match".

So, the answer "int... x" is correct for the JDK6, but for JDK7 the correct answer is "Compilation error"

Follow CodeGalaxy

Mobile Beta

Get it on Google Play
Send Feedback