In reference to the above, I don't think this is correct:
by declaring shapeSuper as List super Shape> shapeSuper
, you are saying that it
can accept any object that is a super
class of Shape
That does seem the intuitive at first glance, but actually I don't think that's how it works. You cannot insert just any superclass of Shape into shapeSuper. superShape is actually a reference to a List which may be restricted to holding a particular (but unspecified) supertype of Shape.
Lets imagine Shape implements Viewable and Drawable. So in this case the superShape reference may actually point to a List
or a List
(or indeed a List
) - but we don't know which one. If it's actually a List
you should not be able to insert a Drawable
instance into it - and the compiler will prevent you from doing this.
The lower bound construct is still actually very useful in making generic classes more flexible. In the following example it allows us to pass into the addShapeToSet method a Set defined to containing any superclass of Shape - and we can still insert a Shape into it:
public void addShapeToSet(Set super Shape> set) {
set.add(new Shape());
}
public void testAddToSet() {
//these all work fine, because Shape implements all of these:
addShapeToSet(new HashSet());
addShapeToSet(new HashSet());
addShapeToSet(new HashSet());
addShapeToSet(new HashSet