Что будет напечатано следующим кодом для 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
Зарегистрируйся сейчас
или Подпишись на будущие тесты