Reputation: 7343
How would one implement generics without type erasure? As I understand it, if I have class Foo<T>
, the T
is replaced basically replaced with Object
and the compiler only has metadata that helps it cast it to the right paramterized type.
But, if reification was implemented, then the T
would be the actual parameterized type (as opposed to Object)... But I don't understand how the compiler would then able to figure out if new T()
is valid invocation (i.e, T might not have a no-arg constructor).
Upvotes: 1
Views: 137
Reputation: 319
In Java specifically, constructors are not inherited by subclasses, so as long as a given parameterized type T
can't be narrowed down to a specific type, you wouldn't be able to run new T()
, since Java is statically typed, regardless of whether or not reification happens. However, instantiation using new
is only one case where classes are used.
The most obvious use to me for generics that aren't erased is being able to use T
in an instanceof
expression:
class Box<T> {
public boolean isInst(Object obj) {
return obj instanceof T;
}
}
There's also the idea of seeing if T
is a superclass or subclass of other classes, or checking equality with classes.
With reification, Java would be able to call static
methods on T
"correctly." Let's say we have the following classes:
class Parent {
void doSomething() { System.out.println("Parent"); }
}
class Child extends Parent {
void doSomething() { System.out.println("Child"); }
}
With those defined, then the following code...
class Box<T extends Parent> {
void test() { T.doSomething(); }
public static void main(String...args) {
Box<Parent> parentBox = new Box<>();
Box<Child> childBox = new Box<>();
parentBox.test();
childBox.test();
}
}
...should print:
Parent
Child
but instead prints:
Parent
Parent
This is because T
turns into Parent
by erasure.
Generic inheritance (as weird as it sounds) could (probably) exist:
public class GenericType<T> {
public class Inner extends T { }
public static void main(String...args) {
GenericType<MyClass>.Inner obj = new GenericType<MyClass>().new Inner();
System.out.println(obj instanceof MyClass); // Prints true
}
}
Upvotes: 2