Generics

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