繁体   English   中英

接受通用集中的子类型

[英]Accepting subtypes in generic sets

我试图找到一种方法来返回通用集,该通用集将接受子类型。 下面的代码返回Set<? extends A> Set<? extends A>到我要添加B

import java.util.Set;
import java.util.HashSet;

public class Test {
    private static class A {}
    private static class B extends A {}

    public Set<? extends A> getSet() {
        return new HashSet<B>();
    }

    public void work() {
        getSet().add(new B()); // compile error
    }
}

导致以下错误:

Test.java:13: cannot find symbol
symbol  : method add(Test.B)
location: interface java.util.Set<capture#320 of ? extends Test.A>
                getSet().add(new B());

通用通配符教程指出不能将B添加到Set<? extends A> Set<? extends A>因为我们不知道B是否是A的子类型,但是我只是这样定义它。 有人可以帮我澄清一下吗?

从根本上讲这是不可能的。

如果该方法实际上返回HashSet<C>怎么办?
您刚刚将B添加到C的集合中。

检查类型安全性时,将忽略方法的内容( return语句)。

如果要执行此操作,则应只返回一个普通的HashSet<A>

问题的实质是,您可以以这种方式使用通配符来遍历扩展公共父对象并执行读取操作的不同对象,但是如果您要写入集合,则该操作将无效。

原因是编译器无法确定将从getSet()方法返回的集合的运行时类型。 它不会解析您编写的代码并尝试做出该决定。

通用通配符教程指出不能将B添加到Set <? 扩展了A>,因为我们不知道B是否是A的子类型,但是我只是这样定义它。

那不是很正确。 说B和C分别扩展a。 getSet()方法可能返回一组B或一组C。您不知道。 因此,您不能仅在其中添加B。 可能是一组C,这将破坏合同。

问题不在于您是否不知道B是A的子类型,而是您不知道A的子类型? 是。

暂无
暂无

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

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