11.13 Limitations and Restrictions on Generic Types
In this section we take a look at implications and restrictions on generic types for instance tests, casting, arrays, variable arity parameters, exception handling, nested classes, and enum types.
Reifiable Types
Concrete parameterized types are used by the compiler and then translated by erasure to their raw types, losing information about the parameterization in the process. In other words, only the raw types of these concrete parameterized types are available at runtime. For example, List<Integer> and List<String> are both erased to the raw type List. The same applies to unbounded parameterized types: List<E> is erased to List.
Non-generic types are not affected by type erasure, and therefore, have not lost any information and are, therefore, available fully at runtime. For example, the types Integer and String remain intact and are present unchanged at runtime.
Types that are completely available at runtime are known as reifiable types—that is, type erasure has not removed any important information about them (see Table 11.5). Types whose information has been affected by erasure are called nonreifiable types (see Table 11.6).
Note that unbounded wildcard parameterized types (Node<?>, MyStack<?>) are reifiable, whereas concrete parameterized types (Node<Number>, MyStack<String>) and bounded wildcard parameterized types (Node<? extends Number>, MyStack<? super String>) are non-reifiable.
As we shall see in the rest of this section, certain operations in Java are only permitted on reifiable types (as their type information is fully intact and available at runtime), and not on non-reifiable types (as their type information is not fully available at runtime, since it has been affected by type erasure).
Table 11.5 Examples of Reifiable Types
Reifiable type | Example |
A primitive type | int, double, boolean |
A non-generic type | Exception, System, Math, Number |
A raw type | List, ArrayList, Map, HashMap |
A parameterized type in which all type arguments are unbounded wildcards (unbounded wildcard parameterized type) | List<?>, ArrayList<?>, Map<?,?>, HashMap<?,?> |
An array type whose component type is reifiable | double[], Number[], List[], HashMap<?,?>[], Number[][] |
Table 11.6 Examples of Non-Reifiable Types
Non-Reifiable type | Example |
A type parameter | E, T, K, V |
A parameterized type with concrete or unbounded type parameters (concrete or unbounded parameterized type) | List<E>, List<String>, ArrayList<Integer>, HashMap<String, Number> Map<K, V> |
A parameterized type with a bound (bounded wildcard parameterized type) | List<? extends Object>, ArrayList<? extends Number>, Comparable<? super Integer> |
An array type whose component type is non-reifiable | List<E>[], ArrayList<Number>[], Comparable<? super Integer>[], HashMap<K, V>[] |
Leave a Reply