Apr 22, 2014

Understanding Java generics with the help of scenarios and working examples -- part 1

Q1. If java.lang.Object is the super type for java.lang.Number and, Number is the super type for java.lang.Integer, am I correct in saying that List<Object> is the super type for List<number> and, List<Number> is the super type for List<Integer>.

A1. No. List<Object> is not the the super type of List<Number>. If that were the case, then you could add objects of any type, and it defeats the purpose of Generics.

/* Compile Error: Type mismatch. Cannot convert from ArrayList<Integer> to List<Number>*/
List<Number> numbers2 = new ArrayList<Integer>();

List<Integer> numbers3 = new ArrayList<Integer>();

/*Compile Error: Cannot instantiate the type ArrayList<? super Integer>*/
List<? super Integer> numbers6 = new ArrayList<? super Integer>();

List<? super Integer> numbers7 = new ArrayList<Integer>();
numbers7.add(Integer.valueOf(5)); //ok

List<? extends Number> numbers5 = new ArrayList<Number>();
//Compile error:  Read only.Can't add

In Generics, wildcards (i.e. ?), makes it possible to work with super classes and sub classes.

Q2. How will you go about deciding which of the following to use?
  • <Number>
  • <? extends Number>
  • <? super Number>

A2. Here is the guide:

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 put objects in a data structure.
3. If you need to do both things (read and add elements), don’t use any wildcard.

Let's take 3 scenarios to explain this.

Scenario 1: A custom generic class GenericSingleTypeScenario class that handles only Integer types.

import java.util.List;

public class GenericSingleTypeScenario<Integer> {

 public void readOnly(List<? extends Number> numbers) {
  for (Number number : numbers) {
   System.out.println("readOnly: " + number);

 public void witeOnly(List<? super Integer> numbers, Integer aNumber) {

 public void witeAndRead(List<Integer> numbers, Integer aNumber) {
  for (Integer integer : numbers) {
   System.out.println("readAndWrite: " + integer);


Add a test class with a main method to test the above class

import java.util.ArrayList;
import java.util.List;

public class GenericSingleTypeScenarioTest {
 public static void main(String[] args) {
  GenericSingleTypeScenario<Integer> singleType = new GenericSingleTypeScenario<Integer>();
  List<Integer> numbers = new ArrayList<Integer>();
  numbers.add(1); //autoboxes 1 to type Integer
  singleType.witeOnly(numbers, 6);  //autoboxes 6 to type Integer
  singleType.witeAndRead(numbers, Integer.valueOf(9));


readOnly: 1
readAndWrite: 1
readAndWrite: 6
readAndWrite: 9

Generics scenarios 2 and 3.



Post a Comment

Subscribe to Post Comments [Atom]

<< Home