Monday, November 9, 2015

How to understand < ? extends Parent> in Java Generics

In Java, polymorphism does NOT apply to generic types. So suppose class Child extends from class Parent, then the following 2 lines, only the first can pass compilation.

  Parent var = new Child();  // compiler is happy with this
ArrayList<Parent> myList = new ArrayList<Child>(); // compilation error

The way to bring the idea of inheritance into Java generic types is using <? extends Parent> or <? super Child>. In this article we'll see how to understand the meaning of syntax <? extends Parent> in Java generics. 


Check another article on how to understand syntax <? super Child> in Java generics.


1. Basic meaning


<? extends Parent> means any class that see class Parent as its ancestor. Parent can be either a class or an interface. (yes, interface is OK although keyword extends is used)


<? extends Parent> can be used for variables definition and  method's parameter


2. Make a collection read-only


If generic types' syntax <? extends Parent> used as method's parameter definition, then the parameter is read-only. Usually it's used with a collection parameter, and that collection is read-only inside the method.


Why ? Let's image you have a method printName defined like

  interface Animal{
String getName();
}
class Dog implements Animal { // omit getName implementation }
class Cat implements Animal { // omit getName implementation }

void printName(List<? extends Animal> animals) {
// Good to read from List
for (Animal animal : animals) {
System.out.println (animal.getName());
}

// Error when write to list, compile fail
animals.add(new Dog());
}

The printName has a paramenter animals as type List<? extends Animal>.  So the following usage are both correct since Dog and Cat are all subclass of Animal.

  printName (new ArrayList<Dog>());
printName (new ArrayList<Cat>());

Now let answer the question about why read-only. In method printName, every element out of list can be guaranteed IS-A type Animal, that's why read from list is OK. But when try to add new element,  the compiler has no idea the input list animals has Dog or Cat in it. Because anyone can call this printName method with eight Dog list or Cat list. This information is unknown to compiler, so all the java compiler can do is  fail there to avoid making severe mistakes adding  a Dog instance into a Cat list.


3. Recap


When use a collection variable with <? extends Parent> style, it means " Hey, I'm gonna use elements in this collection and make sure every one in this collection fulfill IS-A type Parent requirement. But I promise will never ever try to add anything back into this collection"

0 comments:

Post a Comment

Powered by Blogger.

About The Author

My Photo
Has been a senior software developer, project manager for 10+ years. Dedicate himself to Alcatel-Lucent and China Telecom for delivering software solutions.

Pages

Unordered List