The important point about List<? extends Command> is that it's an abstract type. You can't write new List<? extends Command>() and expect something to get created. There are two reasons.
List is an interface, with concrete implementations such as ArrayList, LinkedList and others.
- The wildcard in the type parameter, which means "this could be any type that's a subtype of
Command, including Command itself".
That means that a variable of type List<? extends Command> can reference an object of any of these concrete types
ArrayList<Command>
LinkedList<SpecialCommand>
CopyOnWriteArrayList<ImportantCommand>
and numerous other combinations. Assuming of course that SpecialCommand and ImportantCommand are subtypes of Command.
When you create an object that that variable is going to refer to, you need to be explicit about what concrete type it is. For example
List<? extends Command> myCommandList = new ArrayList<SpecialCommand>();
Once you've done that, of course, you can call some of the usual List methods on myCommandList, such as
Command firstCommand = myCommandList.get(0);
which is fine, because we know that whatever objects are in the list, they'll all be some type of Command. But you can't do things like
SpecialCommand mySpecialCommand = new SpecialCommand();
myCommandList.add(mySpecialCommand);
because the compiler has no way of knowing that you're adding the right kind of object to the list. At this point, myCommandList could equally be a LinkedList<ImportantCommand>, or similar, and adding a SpecialCommand to it needs to be prevented by the compiler.
That means you should only use the type List<? extends Command> if you have a variable where
- you don't care what kind of list it is (
ArrayList, LinkedList or whatever)
- you don't care what kind of
Command is in the list
- you're not going to be trying to add anything to the list.
That means you won't usually use it for a local variable or a field. It's more likely to be a method parameter, where the things passed in might be LinkedList<ImportantCommand> or whatever else; but all you'll be doing in that method is getting objects out of the list, and doing Command type operations on them.
Generics have been in Java since Java 5, including wildcards.