JavaGenerics

Reification

Because some type information is erased during compilation, not all types are available at runtime. Types that are completely available at runtime are known as reifiable types.

Reifiable types include:

  • A primitive type
  • A nonparameterized class or interface type
  • A parameterized type in which all type arguments are unbounded wildcards
  • A raw type
  • An array whose component type is reifiable

Not reifiable types include:

  • A type variable
  • A parameterized type with actual parameters
  • A parameterized type with a bound

Not reifiable types have some limitations:

  • Can't be used for instance testing
  • Cast to not reifiable type usually issues a warning
  • The type must be reifiable to be used in catch statements or to extends Throwable
  • Creation of array instance requires reifiable type
  • Varargs should be of a reifiable type

An example of not reifiable types usage is an inability to use such types for instance creation:

class GenericClass<T> {
  public GenericClass(T field) {
    T t = new T(); // compile-time error: Cannot instantiate the type T
  }
}
This limitation is reasonable since we have no way to guarantee that T will implement any particular constructor.

Another limitation includes instance testing:

class GenericClass<T> {
  public GenericClass(T field) {
    boolean isInt = new Integer(0) instanceof T; // compile-time error:
                                          // cannot perform instance check against type parameter T
  }
}
Instance testing is unavailable since for non-reifiable types the information on exact type is unavailable at runtime.
How did you like the theory?
Report a typo