Java泛型继承警告

时间:2014-04-28 11:53:42

标签: java generics inheritance

以下示例中的foo方法向我们发出警告,而bar则没有?

public class X {

    static class Y {}
    static class Z extends Y {}

    Y y = new Y();

    <T extends Y> T foo() {
        return (T) y; // warning - Unchecked cast from X.Y to T
    }

    Z bar() {
        return (Z) y; // compiles fine
    }

}

2 个答案:

答案 0 :(得分:1)

类型T在编译时被删除到Y,这是泛型如何在Java中工作。因此,当在运行时执行强制转换时,T的类型不可用,它只是字节代码中的Y

bar()编译好,因为所有类型信息都可用(演员表将失败)。但foo()缺少此类型信息,并且不会失败,可能(或者当然,在这种情况下)使方法的类型签名不正确并成为程序中的错误源。

要安全地执行此操作,您需要将类本身传递给方法。

<T extends Y> T foo(Class<T> cls) {
    return cls.cast(y); //No type warning. Will throw an error when cast fails.
}

答案 1 :(得分:0)

因为T是一个类型标记而Z是一个类名。 return (Z) y;它的正确类型转换,但是return (T) y; - 在运行时转换为未知类型。 JVM在运行时对类型标记一无所知(参见this教程部分)。绝对简短,return (T) y; 几乎等效return (Object) y;,从X.YObject取消选中。另请参阅有关return (Z) y;解释的downcasting in Java