归还收藏<! - ?扩展Type - > vs Collection <type> </type>

时间:2013-08-22 14:02:29

标签: java generics wildcard extends

这两种方法有什么区别?

Collection<Type> getTypes();

VS

Collection<? extends Type> getTypes();

Type是类还是接口是否重要? 特别是,在设计API时,首选哪个版本以及为什么?

3 个答案:

答案 0 :(得分:8)

Collection<Type> getTypes();

此处,getTypes()必须返回Collection<Type>(例如ArrayList<Type>HashSet<Type>)。

Collection<? extends Type> getTypes();

在此处,getTypes()可以返回Collection的任何内容Type,例如ArrayList<SubType>HashSet<SubType>。因此,从第一个变量返回的任何内容也可以从第二个变量返回。但是,在第二个中,您不知道集合的类型参数究竟是什么;你只知道它扩展了Type

至于哪个应该是首选,它实际上取决于你想要做什么,以及什么在逻辑上更有意义。请记住,当你有<? extends Type>时,你实际上并不知道?是什么,这有时会阻碍它;通常情况下,第一种变体更适合。您可以在基类中使用第二个变体,并在子类中使用与第一个类似的东西覆盖它,例如:

@Override
Collection<SubType> getTypes() {
    ...
}

答案 1 :(得分:3)

通常不鼓励使用通配符类型返回,请参阅Generics FAQ中的详细原因。简而言之,它可以使返回的对象变得无用(或不太有用),因为使用类型参数的参数的方法只能使用'null'来调用。例如,使用Collection

Collection<? extends Type> collection = ...
collection.add(null); // OK
collection.add(anInstanceOfType); // Error

在这种情况下,这会阻止向集合中添加任何东西(这不是坏事,似乎有人使用它来尝试使返回的集合“只读”,here),但一般情况下这可以引起问题。

答案 2 :(得分:0)

<? extends Type>是一个边界通配符泛型。以这种方式定义的集合可以是任何类型的子类,或Type。即

Collection<Type> typeCollection;
//or
Collection<SubType> subtypeCollection;
//where subtype is...
class SubType extends Type

在这种情况下,重要的是?的类型为Type

Collection<Type> 必须返回Type的集合。即

Collection<Type> collection;

阅读tutorials here.以获取更多信息。您选择的将取决于您的需求。

这是一个例子。在定义可渲染项目组时,我使用有界通配符。例如。

public class SpriteGroup<T extends Sprite>

这将是Sprite的集合,或Sprite的任何子类。这很有用,因为我可以像这样定义组:

SpriteGroup<PhysicalSprite> physicalSprites = new SpriteGroup<PhysicalSprite>();
PhysicalSprite physicalSprite = physicalSprites.get(0);
SpriteGroup<ParticleSprite> particleSprite = new SpriteGroup<ParticleSprite>();
ParticleSprite particle = particleSprite.get(0);

然后任何get / set例程返回我指定的类型(PhysicalSprite,ParticleSprite),这是可取的。

如果我将其定义为:

SpriteGroup<Sprite> spriteGroup = new SpriteGroup();
//all I can retrieve is a sprite, gotta cast now...
Sprite sprite = spriteGroup.get(0);

我需要将它们转换为访问特定于每种Sprite类型的属性。 SpriteGroup的任何子类都将受到限制。