Consider the following classes:
interface Notifiable {
}
class NotifiableImpl1 implements Notifiable {
}
class NotifiableImpl2 implements Notifiable {
}
class NotifiableImpl3 implements Notifiable {
}
It is normal that the following code works:
Set<Notifiable> set = new HashSet<>();
set.add(new NotifiableImpl1());
set.add(new NotifiableImpl2());
set.add(new NotifiableImpl3());
However, the following code does not work:
Set<? extends Notifiable> set2 = new HashSet<>();
set2.add(new NotifiableImpl1());
set2.add(new NotifiableImpl2());
set2.add(new NotifiableImpl3());
I understand it does not work, because it should only be possible to add one concrete subtype of Notifiable
to set2
, but how does it come then, that the following code also does not work?
Set<? extends Notifiable> set2 = new HashSet<>();
set2.add(new NotifiableImpl1());
And maybe more interesting, why does the following work?
Set<Notifiable> set = new HashSet<>();
set.add(new NotifiableImpl1());
set.add(new NotifiableImpl2());
set.add(new NotifiableImpl3());
Set<? extends Notifiable> set3 = set;