Java Generics in no time “? extends” & “? super” explained with a diagram

Generics in Java can be be a bit tricky to get your head around. Hope the explanation below enhances your understanding of generics. This complements 5 Java generics interview Q&As with examples.

Plain old List, List <Object>, and List<?>

The plain old List: is a heterogeneous mixture or a mixed bag that contains elements of all types, for example Integer, String, Pet, Dog, etc.

The List<Object>: is also a heterogeneous mixture like the plain old List, but not the same and can be more restrictive than a plain old List. It is incorrect to think of this as the super type for a collection of any object types.

The List<?>: is a homogenous collection that represents a family of generic instantiations of List like List<String>, List<Integer>, List<Pet>, List<Dog>, etc.

List<?> is the super type for all generic collection as Object[ ] is the super type for all arrays.

What can I assign to? What can I add to the Collection?

When working with Collection & Generics, you need to ask 4 important questions.

1) Can the RHS be assigned to the LHS?
2) What types of objects can I add to the collection?
3) Is it a read only or read & write collection?
4) When to use which wild card (“? extends”, “? super”) ?

If you do the wrong thing, you will get “compile-time” errors. Also, note that you can’t use wildcards on the RHS when assigning and Java 8 supports empty “<>” on the RHS.

Understanding Generics and assign-abilities

Java Generics Overview for assignability

Java Generics Overview for assignability

Note:?” is a wild card meaning anything. “? extends Pet” means “anything that extends a Pet”. Two key points to remember when using the wild card character “?”

Key point 1: you can add

When you are using wildcard List<? super Dog>, means assignable from anything of type Dog, or any superclasses of type Dog. You can add any subclasses of type Dog because of polymorphism where a parent type reference can hold its subclass types.

Key point 2: read only

When you are using wildcard List<? extends Dog>, means assignable from anything of type Dog, or any subclasses of type Dog. This is read only, and can’t add anything to this collection.

Now let’s see a code example based on the above diagram. Click on the diagram to expand.

5 Compile Errors marked in the above code reasoning

#1. List<Object> is NOT the super type of List<Pet>. If it were the case, then you could add pets of any type including Cats, and it defeats the purpose of Generics. List<?> is the super type of List<Pet>. But read only. Can’t add any objects.

#2. Same as #1. If were not illegal, you could add a Cat to a Dog collection. Defeating the purpose of Generics.

#3. List<? extends Dog> means assignable from any objects that are of type Dog or subclasses of Dog. Pet is a superclass of Dog.

#4. You can only add objects of type Dog or subclasses of Dog. Subclasses are possible because of polymorphism , where a parent type reference can hold its subclass object type. So, you can add objects of type Dog or its subclasses like SpanielDog, but NOT its super classes.

#5. List<? super Dog> means assignable from any objects that are of type Dog or superclasses of type Dog. Pet, Object, etc are valid superclasses. But SpanielDog is a subclass.

So, how to decide when to use a wild card, and when not to?

1. Use the ? extends wildcard if you need to retrieve object from a data structure. That is read only. You can’t add elements to the collection.

2. Use the ? super wildcard if you need to add objects to a data structure.

3. If you need to do both things (i.e. read and add objects), don’t use any wildcard.

More code examples to validate your understanding


300+ Java & Big Data Interview FAQs

16+ Java Key Areas Interview Q&As

800+ Java Interview Q&As

300+ Java & Big Data Tutorials

Top