Returnable Collection <? extends Type> vs Collection <Type>

What is the difference between these two methods?

Collection<Type> getTypes(); 

vs

 Collection<? extends Type> getTypes(); 

Does it matter if the type is a class or an interface? Especially when developing an API, which version would be preferable and why?

+4
source share
3 answers
 Collection<Type> getTypes(); 

Here getTypes() should return a Collection<Type> (e.g. ArrayList<Type> or HashSet<Type> ).

 Collection<? extends Type> getTypes(); 

Here getTypes() can return a Collection everything that Type is or is continuing (for example, ArrayList<SubType> or HashSet<SubType> ). Thus, everything that can be returned from the first option can also be returned from the second. In the second, however, you do not know what a collection type parameter really is; you just know that it extends Type .

As for which should be preferable, it really depends on what you are trying to do and what makes sense logically. Keep in mind that when you have <? extends Type> <? extends Type> , you really don't know what ? , and this can sometimes interfere; most often the first option is preferable. You can use the second option in the base class and override it in subclasses with something closer to the first, for example:

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

Returns using the wildcard type are usually discouraged; see the detailed reasons in the Frequently Asked Questions about common features . In short, it can make the returned object useless (or less useful), because methods with parameters that use a type argument can only be called with "null". For example, with Collection :

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

In this case, this prevents adding anything to the collection (which is not so bad, it seems someone is using it to try to make the returned collection "readonly", here ), but in general it can cause problems.

+3
source

<? extends Type> <? extends Type> is a generic generic template. A collection defined this way can be any subclass of Type or Type . i.e.

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

In this case, it is important that ? had type Type .

Collection<Type> should return a Type collection. i.e.

 Collection<Type> collection; 

Read the tutorials here for more information. The choice you choose will depend on your needs.

Here is an example. When defining rendered groups of objects, I use limited wildcards. For instance.

 public class SpriteGroup<T extends Sprite> 

This will be a collection for Sprites or any subclass of Sprite. This is useful because then I can define the following groups:

 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 specified type (PhysicalSprite, ParticleSprite), which is desirable.

If I defined it as:

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

I would have to drop them to access properties specific to each type of sprite. Any subclass of SpriteGroup will also be limited.

0
source

Source: https://habr.com/ru/post/1498393/


All Articles