1

When learning about Java Wildcards i found myself misunderstanding about this theme, so.

  1. Upper Bound allows me to read-only members of generic class
  2. Lower Bound allows me to write to member, but only if it is the types lower bound
List<? extends Vehicle> vehicleList = new ArrayList<Car>(); 
vehicleList.add(new Scooter()); // Compile-time Error!

Compiler won't let us write anything here, because he can't ensure that elements of list would be the correct type (for later reading).

List<? super Car> carList = new ArrayList<Car>();
carList.add(new Car()); // Ok
carList.add(new Vehicle()); // Compile-time Error

This happens because compiler can ensure that lowest type is always Car. And then we can pass it only Car. Am I right?

slier
  • 6,511
  • 6
  • 36
  • 55

2 Answers2

3

You are basically right.

  • List<? extends Vehicle> should be thought of as a list of an unknown subclass of Vehicle (including Vehicle itself).

    As such, nothing can be inserted safely into it (except null).

    When reading from the list, its objects can safely be assigned to Vehicle.

  • Conversely, List<? super Vehicle> is a list of an unknown superclass of Vehicle (including Vehicle).

    Every subclass of Vehicle can be safely inserted into it.

    When reading from the list, its objects can only be assigned to Object.

Marco
  • 479
  • 4
  • 10
2

Remember that List<? super Car> is an abstract type. Think about the actual concrete class of an object of this type. All of these are possibilities, and obviously there are others.

  • ArrayList <Car>
  • ArrayList <Vehicle>
  • ArrayList <Object>
  • LinkedList <Car>
  • LinkedList <Vehicle>
  • LinkedList <Object>

Now, since ArrayList<Car> and LinkedList<Car> don't allow the addition of an object whose class is Vehicle, the compiler can't let you write carList.add(new Vehicle()) if carList is of type List<? super Car>.

Dawood ibn Kareem
  • 77,785
  • 15
  • 98
  • 110