繁体   English   中英

意外类型擦除

[英]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方法中的UU是完全不相关的类型变量。

因此asSubclass()方法返回一个声明的值,该类的类型为某个未知的U类型的子Class ,其中U在这种情况下是MyClass1

您正在尝试将此值分配给类型为Class的变量,并使用某些已知MyClass1子类型。 编译器无法保证它们匹配,因此不允许编译。

如果您愿意,可以强制转换返回的值,但如果类型不匹配,最终可能会在运行时获取ClassCastException

Java编译器无法保证Class对象c与泛型类型U匹配。 由于类型擦除,编译器需要保证类型安全,并确保从c.asSubclass返回的ClassClass<U>匹配,但它不能。

asSubclass方法返回一个Class<? extends U> Class<? extends U> Class类中, U表示传入asSubclassClass类型。 当你打电话给它时,那就是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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM