Рассмотрим следующие классы:Использование подстановочных знаков на интерфейсах
interface Notifiable {
}
class NotifiableImpl1 implements Notifiable {
}
class NotifiableImpl2 implements Notifiable {
}
class NotifiableImpl3 implements Notifiable {
}
Это нормально, что следующий код работает:
Set<Notifiable> set = new HashSet<>();
set.add(new NotifiableImpl1());
set.add(new NotifiableImpl2());
set.add(new NotifiableImpl3());
Однако, следующий код не работает:
Set<? extends Notifiable> set2 = new HashSet<>();
set2.add(new NotifiableImpl1());
set2.add(new NotifiableImpl2());
set2.add(new NotifiableImpl3());
Я понимаю, что это не сработает, потому что только можно добавить один конкретный подтип pe от Notifiable
до set2
, но как получается, что следующий код также не работает?
Set<? extends Notifiable> set2 = new HashSet<>();
set2.add(new NotifiableImpl1());
А может быть, более интересно, почему делает следующие работы?
Set<Notifiable> set = new HashSet<>();
set.add(new NotifiableImpl1());
set.add(new NotifiableImpl2());
set.add(new NotifiableImpl3());
Set<? extends Notifiable> set3 = set;
Я думаю, вы можете найти ответы [здесь] (http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs). Мне нравятся эти утверждения: «1-е использование расширенного подстановочного знака, когда вы получаете только значения из структуры , используйте суперсимвол, когда вы ставите значения в структуру и не используете подстановочный знак, когда вы оба получаете и ставите.' – nachokk
@ nachokk Этот вопрос не о супер vs extends. Хотя ответ может быть похож, это не значит, что вопрос схож. – skiwi
Это правда, это не тот же вопрос, но то же объяснение, что и ответ. – nachokk