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: generics


0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home