Java泛型-具有“扩展”类型的集合参数的方法拒绝有效的参数?

跳过

我试图理解,为什么编译器拒绝/接受以下参数。

我假设两个参数都将被接受,因为两个Set都不包含任何东西,而是Serializable的子元素。
并且是Serializable的子对象-是唯一由方法签名D扩展了Serializable的对象-对吗?

为什么类型D的Set serializables1扩展了Serializable可被接受?
为什么Set serializables2类型扩展Serializable被拒绝?
为什么D扩展了Serializable扩展Serializable在这里不一样吗?

public class GenTest<D extends Serializable> {
    Set<D> serializables1;
    Set<? extends Serializable> serializables2;

    public static void main(String[] args) {
        GenTest<Serializable> g = null;

        g.accept(g.serializables1); // OK - WHY?
        g.accept(g.serializables2); // NOT OK - WHY?
    }

    void accept(Set<D> serializables) {}
}
康斯坦丁·约夫科夫(Konstantin Yovkov)

根据签名,该.accept()方法使用类作用域的D类型参数:

void accept(Set<D> serializables) {}

实例GenTest化为GenTest<Serializable> g = null;表示D将在运行时替换为Serializable

现在,这Set<? extends Serializable> serializables2什么意思?

这意味着serializables2可以为分配一个Set未知子类Serializable编译器没有证据表明该未知子类将D在运行时与替换匹配,因此拒绝编译该代码。

假设您有以下两种类型:

class A implements Serializable { }

class B implements Serializable { }

Set<? extends Serializable> serializables2表示serializables2既可以在运行时分配也可以在运行时Set<A>分配Set<B>假设它被分配了Set<B>

现在,如果您g.serializables仅包含类型的对象A(这是可能的,因为将D替换为Serializable),这意味着在运行时您将获得一个ClassCastException,当尝试将a传递Set<B>给方法时,应为其提供一个Set<A>

更多信息:

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章