Почему в этом определении универсального метода Java есть предупреждение? - PullRequest
9 голосов
/ 30 ноября 2010

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

interface Car {
    <T extends Car> T getCar();
}

class MazdaRX8 implements Car {
    public MazdaRX8 getCar() { // "Unchecked overriding" warning
        return this;
    }
}

С кодом, приведенным выше, моя IDE выдает предупреждение: "Переопределение без проверки: тип возврата требует преобразования без проверки. Найдено: 'MazdaRX8', требуется 'T'"

Что означает это предупреждение?

Это не имеет особого смысла для меня, и Google не выдвинул ничего полезного. Почему это не служит заменой без предупреждений для следующего интерфейса (который также не содержит предупреждений, поскольку ко-вариантные типы возврата разрешены Java)?

interface Car {
    Car getCar();
}

Ответы [ 2 ]

22 голосов
/ 30 ноября 2010

Вы сделали метод универсальным, поэтому вызывающая сторона может сказать, какой тип должен быть возвращен (поскольку вызывающая сторона может указать аргумент типа). Это довольно сложный интерфейс для правильной реализации в Java, где вы не можете найти аргумент типа во время выполнения.

Например, рассмотрим это:

Car mazda = new MazdaRX8();        
FordGalaxy galaxy = mazda.<FordGalaxy>getCar();

Это совершенно законно, что касается интерфейса ... но, очевидно, он не будет работать.

Есть ли причина, по которой интерфейс не является универсальным вместо метода? Тогда MazdaRX8 будет реализовывать Car<MazdaRX8>:

interface Car<T extends Car> {
    T getCar();
}

class MazdaRX8 implements Car<MazdaRX8 > {
    public MazdaRX8 getCar() {
        return this;
    }
}
1 голос
/ 30 ноября 2010

Краткий ответ: это не работает таким образом, и крайне опасно делать то, что вы предлагаете, так как компилятор не может сделать вывод, что должно быть «правильным».У общих методов обычно есть тип, переданный в них параметрами метода, здесь вы ничего не передаете в параметризованном, поэтому T может быть чем угодно, что расширяет Car.

Длинный ответ: посмотрите на это вопрос за ответ.

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