Section 7.5. Reflection for Generics


7.5. Reflection for Generics

Generics change the reflection library in two ways. We have discussed generics for reflection, where Java added a type parameter to the class Class<T>. We now discuss reflection for generics, where Java adds methods and classes that support access to generic types.

Example 7.2 shows a simple demonstration of the use of reflection for generics. It uses reflection to find the class associated with a given name, and it prints out the fields, constructors, and methods associated with the class, using the reflection library classes Field, Constructor, and Method. Two different methods are available for converting a field, constructor, or method to a string for printing: the old toString method and the new toGenericString method. The old method is maintained mainly for backward compatibility. A small sample class is shown in Example 7.3, and a sample run with this class is shown in Example 7.4.

Example 7-2. Reflection for generics

 import java.lang.reflect.*; import java.util.*; class ReflectionForGenerics {   public static void toString(Class<?> k) {     System.out.println(k + " (toString)");     for (Field f : k.getDeclaredFields())       System.out.println(f.toString());     for (Constructor c : k.getDeclaredConstructors())       System.out.println(c.toString());     for (Method m : k.getDeclaredMethods())       System.out.println(m.toString());     System.out.println();   }   public static void toGenericString(Class<?> k) {     System.out.println(k + " (toGenericString)");     for (Field f : k.getDeclaredFields())       System.out.println(f.toGenericString());     for (Constructor c : k.getDeclaredConstructors())       System.out.println(c.toGenericString());     for (Method m : k.getDeclaredMethods())       System.out.println(m.toGenericString());     System.out.println();   }   public static void main (String[] args)   throws ClassNotFoundException {     for (String name : args) {       Class<?> k = Class.forName(name);       toString(k);       toGenericString(k);     }   } } 

Example 7-3. A sample class

 class Cell<E> {   private E value;   public Cell(E value) { this.value=value; }   public E getValue() { return value; }   public void setValue(E value) { this.value=value; }   public static <T> Cell<T> copy(Cell<T> cell) {     return new Cell<T>(cell.getValue());   } } 

Example 7-4. A sample run

 % java ReflectionForGenerics Cell class Cell (toString) private java.lang.Object Cell.value public Cell(java.lang.Object) public java.lang.Object Cell.getValue() public static Cell Cell.copy(Cell) public void Cell.setValue(java.lang.Object) class Cell (toGenericString) private E Cell.value public Cell(E) public E Cell.getValue() public static <T> Cell<T> Cell.copy(Cell<T>) public void Cell.setValue(E) 

The sample run shows that although the reified type information for objects and class tokens contains no information about generic types, the actual bytecode of the class does encode information about generic types as well as erased types. The information about generic types is essentially a comment. It is ignored when running the code, and it is preserved only for use in reflection.

Unfortunately, there is no toGenericString method for the class Class, even though this would be useful. Sun is considering adding such a method in future. In the meantime, all the necessary information is available, and we explain how to access it in the next section.




Java Generics and Collections
Java Generics and Collections
ISBN: 0596527756
EAN: 2147483647
Year: 2006
Pages: 136

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net