Generics
November 16, 2010 Leave a comment
o Improves type safety
– Accepts “parameterized types” (parameters that accept data types)
– Allows for compile time type checking
o Eliminates manual type-checking and type-casting
o JDK 1.5’s Java docs indicate the new generic classes.
o E is a “type parameter” for ArrayList. The name “E” is arbitrary. It simply serves as a placeholder that can be replaced with any Java class type.
o The compiler replaces every occurrence of E in the methods with the type that you specify
when the ArrayList is created.
Class ArrayList<E>
boolean add(E e)
E get(int index)
o Type arguments can be specified when an object is declared/created.
o If an ArrayList is created using a type argument of “String”, the compiler enforces that the list can contain only String objects.
List<String> colors = new ArrayList<String>();
colors.add(“Blue”);
colors.add(“Red”);
colors.add(new Integer(1)); //compile time error
o Using a type argument of “String” with ArrayList and Iterator allows iteration across an ArrayList without any type casts.
List<String> colors = new ArrayList<String>();
colors.add(“blue”);
colors.add(“red”);
for (Iterator<String> i = colors.iterator(); i.hasNext();)
{
String color = i.next(); //no type cast necessary
System.out.println(color);
}
o JDK 1.5’s Javadocs use type parameters named E, K, V, and T. These values stand for element, key, value, and type, respectively.
o The generic version of HashMap allows you to declare a type for both key and value.
Class HashMap<K,V>
boolean put(K key, V value);
V get(Object key);
o Classes that implement the Map<K,V> interface can specify a type for both key and value.
Map<String,Integer> map = new HashMap<String,Integer>();
map.put(“age”, new Integer(30)); //success
map.put(“name”, “Bob”); //compile time error
map.put(new Integer(1), new Integer(10)); //compile time error
o Generic types can be used in method parameters.
o The following method prints a List of Strings. If a parameterized List of any other type is passed in, a compile time error will occur.
o A non-parameterized List can be passed to this method but the compiler will issue a type safety warning. If the List contains any objects other than Strings, a class cast exception will occur.
void printList(List<String> list) {
for (Iterator<String> i = list.iterator(); i.hasNext();) {
System.out.println(i.next());
}
}
o Methods can return parameterized types.
o The following method returns a List of Strings.
o The client that calls this method can receive the return value as a List<String> or as a plain List. However, if it accepts the return type as List, the compiler will issue a type safety warning.
List<String> getList(String one, String two, String three) {
List<String> list = new ArrayList<String>();
list.add(one);
list.add(two);
list.add(three);
return list;
}
o Parameterized types can contain other parameterized types.
o The following code demonstrates using a parameterized ArrayList that contains a collection of parameterized HashMaps.
void printList(List<Map<String,String>> list) {
for (Iterator<Map<String,String>> i = list.iterator(); i.hasNext();) {
Map<String,String> map = i.next();
for (Iterator<Map.Entry<String,String>> j =map.entrySet().iterator(); j.hasNext();) {
Map.Entry entry = j.next();
System.out.println(entry.getKey() + “=” +
entry.getValue());
}
}
}
o Type parameterization is implemented through a process called “erasure”. Erasure removes all type information as the code is compiled.
o The compiler automatically adds any required type casts to the bytecode.
o Since it occurs at runtime, type parameterization does not effect code executed through reflection.
o The JDK 1.5 compiler will issue “unchecked” type safety warnings whenever a non-parameterized collection is used. To suppress warnings when parameterization is not required, method parameters can be declared using the “?” wildcard. For instance, this method accepts a list of any type.
– void printList(List<?> list)
o Generic types can be specify a range of types using the “extends” keyword. For instance, List<? extends Number> declares a List that only contains types that extend Number (or Number itself).
– void printNumberList(List<? extends Number>)