Это может быть глупый вопрос, поэтому, пожалуйста, извините мое невежество.Общие сведения о Java Generics <T extends Class> и <? extends Class>
Допустим, у меня есть класс:
public class Foo<T extends Base> implements Bar<T> {
private Bar<T> wrapped;
public void setWrapped(Bar<T> input) {
wrapped = input;
}
}
Если я называю его:
//Lets just assume methods getNewVal and getFoo exist
Bar<? extends Base> val = getNewVal();
Foo<? extends Base> foo = getFoo();
foo.setWrapped(val);
компилятор говорит foo.execute (значение) ошибка. С сообщением по линиям Метод setWrapped (Bar < захват # 20-of? Extends Base >) в виде Foo < захват # 20-из? extends Base > не применим к аргументам (Bar < capture # 22-of? extends Base >).
Если я пытаюсь изменить Foo быть
public class Foo<T extends Base> implements Bar<T> {
private Bar<T> wrapped;
public void setWrapped(Bar<? extends Base> input) {
wrapped = input;
}
}
Вызов foo.setWrapped (VAL) больше не ошибок. Вместо этого wrapped = input является ошибкой с сообщением в строке Тип несоответствия: не удается преобразовать из Bar < capture # 1-of? extends Base > to Bar <T>.
Что я делаю неправильно? Нет ли способа заставить компилятор быть в порядке с таким вызовом без кастинга?
Это потому, что '?' Не совпадает с '?'. Компилятор не может проверить, что '?' В 'Bar extends Base> 'является * тем же *'? 'как в' Foo extends Base> ', поэтому они несовместимы. – Andreas
Практически нет способа использовать подстановочный знак в качестве возвращаемого типа, что вы делаете во втором примере кода. C.F. PECS http://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super Эти подстановочные знаки предназначены для упрощения использования дженериков с параметрами метода, а не с возвращаемыми типами. – markspace
Пример: 'getNewVal()' возвращает 'Bar', и 'getFoo()' возвращает 'Foo '. Это совершенно верно для первых двух операторов, но не для 'setWrapped()'. –
Andreas