2 comments

  1. Very interesting article. The compiler can (and will) make some assumptions about wildcard types though. Perhaps a useful addition to the example:

    Collection<? extends Animal> dogs = new ArrayList<Dog>();

    dogs.add(new Snake("Hissy")); // This won’t compile..

    dogs.add(null); // This will work, though.

    Animal animal = dogs.get(0); // ** This will work as well!

    "? extends Animal" means "it can be any type, as long as it will fit into an Animal", so assigning the wildcard type to an Animal is safe, and the compiler will allow this. If you write this on the other hand:

    Collection<? super Dog> dogs = new ArrayList<Animal>();

    dogs.add(new Snake("Hissy")); // This won’t compile again..

    dogs.add(new Dog("Roger")); // ** This will work though!

    Animal animal = dogs.get(0); // ** won’t work without a cast!

    "? super Dog" means "it can be any type, as long as I can fit a Dog in it", so assigning a Dog to the wildcard type is safe. On the other hand, this wildcard type has no meaning when assigning from it, because it could be any supertype of Dog, including Object.

    Peter Hendriks

  2. Oops, should have replaced the Collection interface with the List to be able to use the get() method, but I hope you get the point. 🙂

    Peter Hendriks

Comments are closed.