Java lower bound wildcards

I'm struggling to get my head around this and was wondering if someone could explain the reasons for this.

I have three classes:

class Angel {}
class Person extends Angel {}
class Employee extends Person {}

When I attempt to execute this code

public static void insertElements(List<? super Person> list){
    list.add(new Person());
    list.add(new Employee());
    list.add(new Angel());

I get an error:

The method add(capture#5-of ? super Person) in the type List<capture#5-of ? super Person> is not applicable for the arguments (Angel)

I had always read the documentation to mean <? super X > meant any type of X or a superclass of X (so in my case, Angel is a superclass of Person) and should be permitted? Obviously not!

Does anyone have any simple examples?

Solution to answer:

Your intuitive logic says "a List<? super Person> is a list of things that are a Person or a supertype of Person, so naturally I can add an Angel into it". That interpretation is wrong.

The declaration List<? super Person> list guarantees that list will be of such a type that allows anything that is a Person to be added to the list. Since Angel is not a Person, this is naturally not allowed by the compiler. Consider calling your method with insertElements(new ArrayList<Person>). Would it be okay to add an Angel into such a list? Definitely not.

The best way to reason about it is that List<? super Person> is no definite type: it is a pattern describing a range of types that are allowed as an argument. Look at List<Person> as not a subtype of List<? super Person>, but a type that matches this pattern. The operations allowed on List<? super Person> are those that are allowed on any matching type.