[英]Unexpected Type Erasure
I am having an issue with generics and what I presume is type erasure whilst trying to reflect some generic information. 我有一个泛型问题,我猜想是类型擦除,同时试图反映一些通用信息。
I am using a class based on http://www.artima.com/weblogs/viewpost.jsp?thread=208860 to do the reflection, but that isn't the issue. 我正在使用基于http://www.artima.com/weblogs/viewpost.jsp?thread=208860的类进行反射,但这不是问题。
The code below demonstrates the issue: 下面的代码演示了这个问题:
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;
}
}
}
Unfortunately the line 不幸的是行
classIWant = c.asSubclass(MyClass1.class);
Shows the following error 显示以下错误
java: incompatible types
required: java.lang.Class<U>
found: java.lang.Class<capture#4 of ? extends MyClass1>
And that's really confusing me. 这真让我困惑。 U extends MyClass1 and therefore U is a MyClass1.
U扩展了MyClass1,因此U是MyClass1。
Obviously there is some piece of type erasure I am not understanding here - can anybody help, please. 显然有一些类型的擦除我不明白 - 请有人帮忙。 BTW this is Java 1.7.0_40
BTW这是Java 1.7.0_40
Thanks 谢谢
Conrad Winchester 康拉德温彻斯特
The method asSubclass()
is implemented like so 方法
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());
}
with a return type of Class<? extends U>
返回类型为
Class<? extends U>
Class<? extends U>
. Class<? extends U>
。 Note, that your U
and the U
in the asSubclass
method are completely unrelated type variables. 请注意,
asSubclass
方法中的U
和U
是完全不相关的类型变量。
So the method asSubclass()
returns a value declared with the type Class
of some unknown subtype of U
, where U
in this case is MyClass1
. 因此
asSubclass()
方法返回一个声明的值,该类的类型为某个未知的U
类型的子Class
,其中U
在这种情况下是MyClass1
。
You are trying to assign this value to a variable of type Class
with some known subtype of MyClass1
. 您正在尝试将此值分配给类型为
Class
的变量,并使用某些已知的MyClass1
子类型。 The compiler can't guarantee that they match and therefore doesn't allow compilation. 编译器无法保证它们匹配,因此不允许编译。
You can cast the returned value if you wish, but may end up getting ClassCastException
at runtime, if the types don't match. 如果您愿意,可以强制转换返回的值,但如果类型不匹配,最终可能会在运行时获取
ClassCastException
。
The Java compiler is unable to guarantee that the Class
object c
matches the generic type U
. Java编译器无法保证
Class
对象c
与泛型类型U
匹配。 Because of type erasure, it is up to the compiler to guarantee type safety, and ensure that the Class
coming back from c.asSubclass
matches Class<U>
, but it can't. 由于类型擦除,编译器需要保证类型安全,并确保从
c.asSubclass
返回的Class
与Class<U>
匹配,但它不能。
The asSubclass
method returns a Class<? extends U>
asSubclass
方法返回一个Class<? extends U>
Class<? extends U>
. Class<? extends U>
。 In the Class
class, U
represents the type of Class
passed into asSubclass
. 在
Class
类中, U
表示传入asSubclass
的Class
类型。 When you call it, that is c
. 当你打电话给它时,那就是
c
。 But the compiler cannot guarantee that this return type matches your own declared <U extends MyClass1>
. 但编译器无法保证此返回类型与您自己声明的
<U extends MyClass1>
匹配。 They could be different subclasses of MyClass1
. 它们可以是
MyClass1
不同子类。
If you can guarantee that c.asSubclass
will return a Class<U>
, then cast it as a Class<U>
: 如果你能保证
c.asSubclass
将返回一个Class<U>
然后将它转换为Class<U>
classIWant = (Class<U>) c.asSubclass(MyClass1.class);
You will receive an "unchecked cast" warning. 您将收到“未经检查的演员”警告。 This is there because the compiler cannot guarantee that is really is a
Class<U>
, but you are saying that it is. 这是因为编译器不能保证它确实是一个
Class<U>
,但你说的是它。 Be careful as this may result in a hard-to-track-down ClassCastException
elsewhere, even after you return the U
. 请注意,即使在返回
U
之后,这可能会导致其他地方难以跟踪ClassCastException
。 Do this only if you can guarantee the type safety yourself. 只有在您可以自己保证类型安全的情况下才能这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.