Что будет напечатано следующим кодом для 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 правильным будет ответ "Ошибка компиляции"

Слідкуй за CodeGalaxy

Мобільний додаток Beta

Get it on Google Play
Зворотній Зв’язок
Продовжуйте вивчати
тести з Java
Cosmo
Зареєструйся Зараз
або Підпишись на майбутні тести