0

I am a novice, I met a problem, do not understand, as follows:

class Animal {}

class Cat extends Animal {}

class Garfield extends Cat {}

public class Demo {
    public static void main(String[] args) {

        List<? super Cat> list = new ArrayList<>(); // list can include cat and animal

        list.add(new Cat());      // perfect !!
        list.add(new Garfield()); // wait... why can ??
        list.add(new Animal());   // wait... why can't ?? 
    }
}

Thank you very much!

hackk
  • 1

1 Answers1

3

? super Cat means "Cat and it's superclasses, up to Object", so it can be either List<Cat> or List<Animal> - both are subtypes of List<? super Cat>.
You only know the lower bound (which is why it's called lower bounded wildcard), so you can add only objects of type Cat and it's descendants: they definitely can be added to collection, whichever the actual type of elements inside is - that's why you can add new Cat() and new Garfield() - they both are Cats and Animals.
But, you cannot add Animals - since it can be a List of Cat, for example, and Animal is-not-a Cat (Cat is-an Animal). Same logic, you cannot assign an Animal value to a Cat variable, since Cat extends type of Animal, and Animal, therefore, lacks the new functionality Cat provides.

Andrew Vershinin
  • 1,880
  • 9
  • 13
  • Oh! I see! Thank you very much! – hackk Jan 23 '21 at 05:55
  • Isn't `Animal` a superclass of `Cat`? – Sal Jan 23 '21 at 06:59
  • Yes, `Animal` is a superclass of `Cat`, but `? super Cat` might stand for `Feline` and an `Animal` is not a `Feline`. Basically to a `List super Cat>` you can only write `Cat` and read `Object` (it is a consumer of elements), from a `List extends Cat>` you can only read `Cat`s and write `null` (it is a supplier of elements). – Piotr P. Karwasz Jan 23 '21 at 12:46
  • 1
    I've updated the answer with more detailed explanation – Andrew Vershinin Jan 23 '21 at 16:52