繁体   English   中英

java中的通用集合和通配符

[英]Generic collection & wildcard in java

在以下情况下我遇到问题,请参阅下面的内联评论:

public void exampleMethod() {
    //Intuitively I would expect this to mean that test is set containing objects 
    //that subclass AbstractGroup
    Set<? extends AbstractGroup> test;

    //Yet the compiler complains here and I do not understand why?

    test.add(new AnyAbstractGroupSubGroup());

    //I would guess that a method call such as this at runtime

    test = new HashSet<SubGroupA>()

    //would mean that only objects of subgroupA can be added to the collection, but then
    //what is the point in using the wildcard in the first place?  
}
//Intuitively I would expect this to mean that test is set containing objects 
//that subclass AbstractGroup
Set<? extends AbstractGroup> test;

不,这意味着它是一组特定的? 它扩展了AbstractGroup。 你和编制者都没有办法知道那是什么? 是的,所以你无法向该套装添加任何东西。

您可以将集合的值分配给AbstractGroup类型的变量,但不能相反。

相反,你需要这个:

Set<? super AbstractGroup> test;

这个原则有时被称为PECS ,并在这个答案中得到了很好的解释。

Set<? extends AbstractGroup> test;

这意味着您的集合可以是扩展AbstractGroup的任何对象的集合,但通常编译器不允许您向该集合添加内容(因为它无法判断您是否SubGroupB添加到Set<SubGroupA>等)。

test = new HashSet<SubGroupA>()

您的实际集只包含SubGroupA类型的SubGroupA及其子类。 但是,编译器仍然不知道test的内容是什么(见上文)。

that map to AbstractGroup (which the compiler checks for). 通配符的要点是:您可以将任何集合分配给使用AbstractGroup或子类参数化的变量,从而确保您可以将该映射中所有对象AbstractGroup (编译器检查)。

如果您想拥有一个可以包含任何AbstractGroup对象的集合,则不要使用通配符。

//this would compile (under the assumption that SubGroupA extends AbstractGroup)
Set<? extends AbstractGroup> test = new HashSet<SubGroupA>(); 

//this wouldn't compile, since the compiler doesn't know the type of test (it might change at runtime etc.)
test.add(new SubGroupA());


//this wouldn't compile since AbstractGroup and SubGroupA are not the exact same type (hence the wildcard would be needed here)
Set<AbstractGroup> test = new HashSet<SubGroupA>();

//this would compile
Set<AbstractGroup> test = new HashSet<AbstractGroup>();
test.add(new SubGroupA());

你不需要这里的通配符在你的情况下,它就足够了

Set<AbstractGroup> test;

然后,您可以将AbstractGroup的任何子类放入集合中。

此外,它看起来不像您在上面的代码中初始化测试。

暂无
暂无

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

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