[英]Unexpected Type Erasure
我有一个泛型问题,我猜想是类型擦除,同时试图反映一些通用信息。
我正在使用基于http://www.artima.com/weblogs/viewpost.jsp?thread=208860的类进行反射,但这不是问题。
下面的代码演示了这个问题:
private <U extends MyClass1> U doSomething(MyClass2<U> p) {
Class<U> classIWant = null;
for (Class<?> c : GenericTypeUtils.getTypeArguments(MyClass2.class, p.getClass())) {
if (MyClass1.class.isAssignableFrom(c)) {
classIWant = c.asSubclass(MyClass1.class);
break;
}
}
}
不幸的是行
classIWant = c.asSubclass(MyClass1.class);
显示以下错误
java: incompatible types
required: java.lang.Class<U>
found: java.lang.Class<capture#4 of ? extends MyClass1>
这真让我困惑。 U扩展了MyClass1,因此U是MyClass1。
显然有一些类型的擦除我不明白 - 请有人帮忙。 BTW这是Java 1.7.0_40
谢谢
康拉德温彻斯特
方法asSubclass()
就像这样实现
public <U> Class<? extends U> asSubclass(Class<U> clazz) {
if (clazz.isAssignableFrom(this))
return (Class<? extends U>) this;
else
throw new ClassCastException(this.toString());
}
返回类型为Class<? extends U>
Class<? extends U>
。 请注意, asSubclass
方法中的U
和U
是完全不相关的类型变量。
因此asSubclass()
方法返回一个声明的值,该类的类型为某个未知的U
类型的子Class
,其中U
在这种情况下是MyClass1
。
您正在尝试将此值分配给类型为Class
的变量,并使用某些已知的MyClass1
子类型。 编译器无法保证它们匹配,因此不允许编译。
如果您愿意,可以强制转换返回的值,但如果类型不匹配,最终可能会在运行时获取ClassCastException
。
Java编译器无法保证Class
对象c
与泛型类型U
匹配。 由于类型擦除,编译器需要保证类型安全,并确保从c.asSubclass
返回的Class
与Class<U>
匹配,但它不能。
asSubclass
方法返回一个Class<? extends U>
Class<? extends U>
。 在Class
类中, U
表示传入asSubclass
的Class
类型。 当你打电话给它时,那就是c
。 但编译器无法保证此返回类型与您自己声明的<U extends MyClass1>
匹配。 它们可以是MyClass1
不同子类。
如果你能保证c.asSubclass
将返回一个Class<U>
然后将它转换为Class<U>
classIWant = (Class<U>) c.asSubclass(MyClass1.class);
您将收到“未经检查的演员”警告。 这是因为编译器不能保证它确实是一个Class<U>
,但你说的是它。 请注意,即使在返回U
之后,这可能会导致其他地方难以跟踪ClassCastException
。 只有在您可以自己保证类型安全的情况下才能这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.