[英]Understand Type Erasure in Java
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. 据我了解,如果我有
class Foo<T>
,则T
基本上被Object
取代,并且编译器仅具有帮助它将其转换为正确的参数化类型的元数据。
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 (ie, T might not have a no-arg constructor). 但是,如果实现了实现,则
T
将是实际的参数化类型(与Object相对)...但是我不明白编译器如何才能确定new T()
是否有效调用(即,则T可能没有no-arg构造函数)。
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 . 具体来说,在Java中,构造函数不会被子类继承,因此,只要无法将给定的参数化类型
T
缩小为特定类型,就无法运行new T()
,因为Java是静态类型的, 不管是否发生了改造 。 However, instantiation using new
is only one case where classes are used. 但是,使用
new
实例化只是使用类的一种情况 。
The most obvious use to me for generics that aren't erased is being able to use T
in an instanceof
expression: 对于我来说,不被删除的泛型最明显的用途是能够在
instanceof
表达式中使用T
:
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. 还有一个想法,就是查看
T
是其他类的超类还是子类,或者检查类的相等性。
With reification, Java would be able to call static
methods on T
"correctly." 借助这种技术,Java可以“正确”调用
T
上的static
方法。 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. 这是因为
T
通过擦除变成了Parent
。
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
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.