Что будет напечатано следующим кодом для JDK > 7?

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

Если в классе отсутствует метод, типы формальных параметров которого в точности совпадают с типами фактических аргументов, то компилятор пытается применить следующие преобразования:

1a. Расширение примитивного типа, например, byte -> int
1b. Расширение ссылочного типа, например, Integer -> Object

2a. Unboxing conversion (с возможным расширением примитивного типа), например, Integer -> int
2b. Boxing conversion (с возможным расширением ссылочного типа), например, byte -> Byte -> Object

Видно, что никакими из перечисленных преобразований нельзя из пары (byte, Integer) получить пару (Integer, int)
Уже после перечисленных преобразований компилятор пытается применить varargs.

В данном примере это возможно двумя способами:
(byte, Integer) -> ( (1a), (2a) ) -> (int, int) -> (int ...) (byte, Integer) -> ( (2b), (1b) ) -> (Object, Object) -> (Object ...)

В данной ситуации JDK6 действует с нарушением спецификации и генерирует вызов метода (int ...). В JDK7 эта ошибка уже исправлена и компилятор выдаёт ошибку "reference to var is ambiguous, both method var(Object...) in Main and method var(int...) in Main match".

Получается, что ответ "int... x" верен только для JDK6, а для JDK7 правильным будет ответ "Ошибка компиляции"

Follow CodeGalaxy

Mobile Beta

Get it on Google Play
Send Feedback
Keep exploring
Java quizzes
Cosmo
Sign Up Now
or Subscribe for future quizzes