这两种方法有什么区别?
Collection<Type> getTypes();
VS
Collection<? extends Type> getTypes();
Type是类还是接口是否重要? 特别是,在设计API时,首选哪个版本以及为什么?
答案 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
的任何子类都将受到限制。