简体   繁体   English

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

[英]Java generics unchecked warnings for extended classes

I have the following code: 我有以下代码:

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();
        }

    }
}

Why is the cast to (this) object type unsafe? 为什么转换为(this)对象类型不安全? When Bar implements Coo, isn't the generic saying that returned cool must be of type T, which extends Bar or its subclasses? 当Bar实现Coo时,返回cool的通用说法不一定是T类型,它扩展了Bar或它的子类?

Because this in Bar has type Bar<T extends Bar<T>> but not T , the compiler generates warnings for Bar#doSomething . 因为thisBar已键入Bar<T extends Bar<T>>但不T ,编译器生成的警告Bar#doSomething The following won't generate any warnings: 以下内容不会产生任何警告:

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

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

}

The body of Bar#cool expects this to be a subtype of T which is not the case. Bar#cool的主体期望thisT的子类型,但事实并非如此。 In Bar#cool , this has type Bar<T extends Bar<T>> and is a subtype of Coo<T> but not T . Bar#coolthis有类型Bar<T extends Bar<T>>并且是Coo<T>的子类型但不是T

T extends Bar<T> , but Bar<T> (the type of this ) does not extend T . T延伸Bar<T>Bar<T>类型this )不延伸T

Imagine 想像

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

Then the method becomes inherited as: 然后该方法继承为:

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

which is obviously not right. 这显然是不对的。

It is not possible to do what you want with generics. 用泛型做你想做的事是不可能的。 It is a big misconception among people. 这是人们的一个很大的误解。 They think that recursive bounds will allow you to do self-types. 他们认为递归边界将允许你做自我类型。 But recursive bounds are ALMOST NEVER useful in Java. 但是递归边界在Java中几乎没有用。 99% of the places where you see people write interface Bar<T extends Bar<T>> , it would be just as good to write it as interface Bar<T> . 99%的地方你看到人们编写interface Bar<T extends Bar<T>> ,把它写成interface Bar<T>就好了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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