Issue
I'm currently learning java generics and below is a list of types in java that is non-reifiable.
A type is not reifiable if it is one of the following:
• A type variable
(such as T
)
• A parameterized type with actual parameters
(such as List<Number>, ArrayList<String>, or Map<String, Integer>
)
• A parameterized type with a bound
(such as List<? extends Number> or Comparable<? super String>
)
I understand why parameterized type with actual parameter and parameterized type with bound is non-refieable, because after runtime erasure, the only type information left is List
, but why is type variable (such as T
) a non-reifiable type? I thought at runtime, after type erasure, T
would become Object
(given T
is an unbound type parameter), so the type information is available.
Is there something wrong with my understanding?
Solution
The docs state that
A non-reifiable type does not have all of its information available at runtime.
The type of T
at runtime is Object
so information is lost. An example of the information that is lost is how an object can be created. Consider this class:
public class A {
private int a;
public A() {
a = 5;
}
}
Now look at this not compiling code:
public class Generic<T> {
T foo() {
return new T(); //Compiler Error!
}
}
If this was allowed and you were instantiating a Generic<A> g = new Generic<>();
and calling g.foo()
, the constructor of T
could not be called, because, at runtime, T
is only known as Object
. Therefore, an valid instance of A
cannot be created and returned. You even cannot be sure which information a constructor of T
needs. The information how T
can be constructed is lost.
That is one reason why type parameters must be non-reifiable types.
Answered By - Tobias
Answer Checked By - Cary Denson (JavaFixing Admin)