Limitations and Restrictions on Generic Types – Generics

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 typeExample
A primitive typeint, double, boolean
A non-generic typeException, System, Math, Number
A raw typeList, 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 reifiabledouble[], Number[], List[],
HashMap<?,?>[], Number[][]

Table 11.6 Examples of Non-Reifiable Types

Non-Reifiable typeExample
A type parameterE, 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-reifiableList<E>[],
ArrayList<Number>[],
Comparable<? super Integer>[],
HashMap<K, V>[]

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *