Почему расширение перегружает метод Boxing и var-args при перегрузке метода? - PullRequest
8 голосов
/ 24 января 2010

Я готовлюсь к экзамену по SCJP, и при изучении расширяющейся части мне дают ввиду, что расширение превосходит и Boxing, и Var-args при перегрузке, но нет четкого объяснения. Пробовал искать, но лучшего ответа не получил.

Один ответ, который я получил, заключается в том, что компилятор выбирает старый стиль, прежде чем он выберет новый. Но я не уверен.

Редактировать: я знаю, что расширение предпочтительнее, чем бокс и вар-арги. но ПОЧЕМУ мой вопрос. из которых я знаю один. любые другие причины.

Ответы [ 7 ]

17 голосов
/ 24 января 2010

Да, компилятор "выбирает старый стиль вместо нового стиля" из-за требований совместимости.Представьте себе некоторый код, написанный до выхода Java 5, который неожиданно изменил поведение при компиляции под Java 5!Это было бы плохо.

Расширение конверсии происходило с момента появления Java, но автобокс и переменные являются новыми для Java 5.

5 голосов
/ 24 января 2010

Вот пример этого:

class Widen {

    private static void widen(long k) {
        System.out.println("Converted to long: " + k);
    }

    private static void widen(int ... k) {
        System.out.println("Converted to varargs: " + k);
    }

    private static void widen(Integer k) {
        System.out.println("Converted to Integer: " + k);
    }

    public static void main(String ... args) {
        int value = 3;
        widen(value);  // Output: Converted to long: 3
    }
}    

Таким образом, все это означает, что он расширится перед автобоксом и использованием varargs. Если бы мы убрали метод widen с параметром long, он бы выбрал autoboxing перед varargs.

1 голос
/ 24 января 2010

Компилятор должен поддерживать совместимость с предыдущими версиями Java. Кроме того, компилятор выбирает наиболее производительное / наименьшее изменение аргумента. Повышение до другого примитива бьет создание объекта-обертки, и это бьет создание массива с точки зрения использования памяти и производительности.

0 голосов
/ 11 июля 2011
class Widen {
    private static widen(long k) {
        System.out.println("Converted to long: " + k);
    }
    private static widen(int ... k) {
        System.out.println("Converted to varargs: " + k);
    }
    private static widen(Integer k) {
        System.out.println("Converted to Integer: " + k);
    }
    public static void main(String ... args) {
        int value = 3;
        widen(value);  // Output: Converted to long: 3
    }
} 

, чтобы решить вышеупомянутый ум это:

расширение бьет по боксу, бокс бьет по varargs

выход будет Пересчитано в длинный: 3

0 голосов
/ 26 августа 2010

расширяется, бьет по боксу, бокс бьет дженерики, дженерики бьют варагс

0 голосов
/ 24 января 2010

Причина, по которой расширение работает лучше, заключается в том, что это простая операция для подписи расширения, единственная инструкция для большинства процессоров. Упаковка требует выделения кучи, а доступ к упакованным объектам обходится дороже, для чего требуется как минимум дополнительный доступ к памяти.

Даже без проблем с совместимостью мне кажется, что вы хотите, чтобы язык сначала предпочел самую быструю перегрузку, если это не создает проблем хуже.

0 голосов
/ 24 января 2010

Я не знаю о вас, но я бы предпочел, чтобы компилятор передал мой byte как int, а не Byte Рассмотрим накладные расходы. И варагс тоже требует бокса.

Другими словами, причина в эффективности. Конструкция языка предпочитает более эффективный механизм вызова, для которого не требуется выделять элемент в штучной упаковке.

«Требуется», спросите вы? Функции varargs ожидают получить массив Object, и он не может включать примитивный тип.

Совместимость тоже не плохая причина.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...