Ковариантные возвращаемые типы при переопределении методов и списка List <T>vs.' - PullRequest
2 голосов
/ 18 мая 2019

Интуитивно (и неправильно). Я думаю, что List<T> не более специализирован, чем List<? extends T>, поэтому ниже не будет компилироваться (потому что ковариация возвращаемого типа требует, чтобы возвращаемый тип в Derived был тем же или подтипом этого типа). в базе) - но он компилируется! Я (ошибочно) ожидал, что он скомпилируется, если мы поменяем местами методы.

Но какова строгая (и правильная) аргументация, почему это работает?

class Base {
    <T> List<? extends T>  f1() {
        return null;
    }
}

class Derived extends Base {

    <T> List<T>  f1() {   // fine !!! Not compile error.
        return null;
    }    
}

Кроме того, я что-то неправильно понимаю - оба метода имеют <T> - поэтому эти два T когда-либо могут быть разными T?

1 Ответ

1 голос
/ 19 мая 2019

Почему бы это не скомпилировать?List<T> является подтипом List<? extends T>, то есть он компилируется просто отлично:

List<String> one = List.of("one");
List<? extends String> two = one;

Также сказано, что подстановочный знак с ограниченным типом делает тип ковариантным,

...