5

这两种方法有什么区别?

Collection<Type> getTypes();

对比

Collection<? extends Type> getTypes();

Type 是类还是接口有关系吗?特别是在设计 API 时,首选哪个版本,为什么?

4

3 回答 3

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() {
    ...
}
于 2013-08-22T14:08:18.010 回答
3

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

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

在这种情况下,这可以防止向集合中添加任何内容(这不是一件坏事,似乎有人使用它来尝试使返回的集合“只读”,此处),但通常这会导致问题。

于 2013-08-22T14:21:44.887 回答
0

<? extends Type> is a bounding wildcard generic. A collection defined in this way could be of any subclass of type, or Type. ie.

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

All that matters in this case is that ? is of type Type.

Collection<Type> must be return a collection of Type. ie.

Collection<Type> collection;

Read the tutorials here. for more information. Which you chose will depend on your needs.

Here's an example. I use bounded wildcards when defining renderable item groups. For example.

public class SpriteGroup<T extends Sprite>

This would be a collection for Sprites, or any subclass of Sprite. This is useful because then I can define groups like so:

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

Any get/set routines then return the type I specified (PhysicalSprite, ParticleSprite), which is desirable.

If I'd defined it as:

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

I'd need to cast them to access properties specific to each type of Sprite. Any subclass of SpriteGroup would be restricted likewise.

于 2013-08-22T14:08:47.683 回答