了解Java中的类型擦除
如果没有类型擦除,如何实现泛型?据我所知,如果我有了解Java中的类型擦除,java,type-erasure,Java,Type Erasure,如果没有类型擦除,如何实现泛型?据我所知,如果我有类Foo,T基本上被对象替换,编译器只有元数据可以帮助它将其转换为正确的参数化类型 但是,如果实现了具体化,那么T将是实际的参数化类型(与对象相反)。。。但是我不明白编译器如何才能判断new t()是否是有效的调用(即,t可能没有无参数构造函数)。在Java中,构造函数不是由子类继承的,因此只要给定的参数化类型t不能缩小到特定类型,您将无法运行newt(),因为Java是静态类型的,无论是否发生具体化。然而,使用new实例化只是使用类的一种情况
类Foo
,T
基本上被对象替换,编译器只有元数据可以帮助它将其转换为正确的参数化类型
但是,如果实现了具体化,那么T
将是实际的参数化类型(与对象相反)。。。但是我不明白编译器如何才能判断new t()
是否是有效的调用(即,t可能没有无参数构造函数)。在Java中,构造函数不是由子类继承的,因此只要给定的参数化类型t
不能缩小到特定类型,您将无法运行newt()
,因为Java是静态类型的,无论是否发生具体化。然而,使用new
实例化只是使用类的一种情况
瞬间
对我来说,不被擦除的泛型最明显的用途是能够在instanceof
表达式中使用t
:
class Box<T> {
public boolean isInst(Object obj) {
return obj instanceof T;
}
}
有了这些定义,下面的代码
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();
}
}
而是打印:
Parent
Parent
这是因为T
通过擦除变成了Parent
遗产
泛型继承(听起来很奇怪)可能(可能)存在:
公共类GenericType{
公共类内部扩展T{}
公共静态void main(字符串…参数){
GenericType.Inner obj=新建GenericType().new Inner();
System.out.println(MyClass的obj实例);//打印为true
}
}
确切地说,这就是为什么在通过反射调用随机构造函数时会出现异常的原因。此外,您可以指定通过编译器在此处抱怨的方式缩小类型定义的范围:类测试{void t(ts){new t();}}
基本语法如下:t newT=(t)s.getClass().getConstructor().newInstance()代码>不知道如何避免未经检查的强制转换警告,尽管无法使用泛型避免类型擦除。他们就是这样工作的。但是,通常不会将完全不同的类传递给泛型类。new T()
限制与类型擦除没有直接关系。如果您在编译时不知道t
,那么无论new t()
在运行时是否可用,您都不知道它是否有效。C#使用求解,其中T:new()
和Java理论上可以做类似的事情。
Parent
Child
Parent
Parent
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
}
}