Google

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>();


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


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


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


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


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) {
  numbers.add(aNumber);
 }

 public void witeAndRead(List<Integer> numbers, Integer aNumber) {
  numbers.add(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.readOnly(numbers);
  singleType.witeOnly(numbers, 6);  //autoboxes 6 to type Integer
  singleType.witeAndRead(numbers, Integer.valueOf(9));
  
 }
}


Output:

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


Generics scenarios 2 and 3.

Labels:

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home