0
import java.util.*;    

class Test
{
    public static class Base
    {           
    }

    public static class Derived1
        extends Base
    {               
    }

    public static class Derived2
        extends Base
    {               
    }

    public static void main (String[] args)
    {
        //Example1.
        List<? extends Base> e = new ArrayList<Base>();
        e.add(new Derived1()); //this won't compile

        //Example2.
        List<? super Base> b = new ArrayList<Base>();
        b.add(new Derived1()); //this compiles
    }
}

2 Answers2

3

List<? super Base> b can be assigned either a List<Base> or a List<Object>. A Derived1 instance can be added to both, so the b.add(new Derived1()) statement passes compilation.

On the other hand, List<? extends Base> e may be assigned a List<Derived2>, so the compiler doesn't allow to add a Derived1 instance to it.

Eran
  • 387,369
  • 54
  • 702
  • 768
1

See What is PECS (Producer Extends Consumer Super)?.

If you are adding something to a List<T>, then the list is a consumer of the thing you are adding. As such, the type of the list elements, T, must be the same as the thing you are trying to add or a supertype.

Community
  • 1
  • 1
Andy Turner
  • 137,514
  • 11
  • 162
  • 243