Java泛型未选中扩展类的警告

时间:2012-12-11 00:59:54

标签: java generics

我有以下代码:

public class Foo {

    interface Coo<T> {
        public T cool();
    }

    abstract class Bar<T extends Bar<T>> implements Coo<T>  {

        @SuppressWarnings("unchecked")
        T doSomething() {
            return (T) this;
        }

        @SuppressWarnings("unchecked")
        @Override
        public T cool() {
            return (T) this;
        }

    }

    class FooBar extends Bar<FooBar> {
        @Override
        public FooBar cool() {
            return super.cool();
        }

    }
}

为什么转换为(this)对象类型不安全?当Bar实现Coo时,返回cool的通用说法不一定是T类型,它会扩展Bar或它的子类吗?

2 个答案:

答案 0 :(得分:3)

由于this中的Bar具有Bar<T extends Bar<T>>类型而非T,因此编译器会为Bar#doSomething生成警告。以下内容不会产生任何警告:

abstract class Bar<T extends Bar<T>> {

    Bar<T> doSomething() {
        return this;
    }

}

Bar#cool的正文期望this成为T的子类型,而不是Bar#cool。在this中,Bar<T extends Bar<T>>的类型为Coo<T>,其子类型为T,但不是{{1}}。

答案 1 :(得分:1)

T扩展了Bar<T>,但Bar<T>this的类型)未扩展T

想象

class A extends Bar<A> { ... }
class B extends Bar<A> { ... }

然后该方法继承为:

class B {
    A doSomething() {
        return (A) this;
    }
}

这显然是不对的。

使用泛型无法做到你想要的。这是人们的一个很大的误解。他们认为递归边界将允许你做自我类型。但是递归边界在Java中几乎没有用。在您看到人们写interface Bar<T extends Bar<T>>的地方中,有99%的地方将其写为interface Bar<T>一样好。