<? extends> Java syntax
This code:
List<? extends Reader> weirdList; weirdList.add(new BufferedReader(null)); has a compilation error
The add (capture # 1-of? Extends Reader) method in the List type is not applicable for arguments (BufferedReader)
Why? BufferedReader expands the reader, so why is it not a βmatchβ?
For the variable you specified:
List<? extends Reader> weirdList; All of the following assignments are valid:
weirdList = new ArrayList<Reader>(); weirdList = new ArrayList<FileReader>(); weirdList = new ArrayList<BufferedReader>(); weirdList = new ArrayList<InputStreamReader>(); Hope this explains your compilation error. What you are trying makes sense if weirdList contains a value of type ArrayList<BufferedReader> , but does not make sense for a value of type ArrayList<FileReader> . Since a variable of type List<? extends Reader> List<? extends Reader> can contain a value of any type (and more!), Java causes an error.
Java generics are hard to find. Can you think of a List<? extends Reader> type List<? extends Reader> List<? extends Reader> as the most useful for assigning or parameter types in methods so that they can accept a wide variety of types. For "regular use" you will probably be better off with a "bare" generic type like List<Reader> or even List<BufferedReader> .
When <? extends Reader> compiler see <? extends Reader> <? extends Reader> , it suggests that it can be any type that is or extends Reader . It might be something that is not compatible with BufferedReader , like StringReader . Therefore, if the generic type in the class definition is displayed in a method parameter, such as add , and the instance type has something like <? extends Something> <? extends Something> , the compiler should disable it for type security reasons. In this example, it could be a List<StringReader> , so you cannot add a BufferedReader here.
List<? extends Reader> weirdList List<? extends Reader> weirdList can contain a link to any type of List that stores any type of Reader . Thus, it is possible that
List<? extends Reader> weirdList1 = new ArrayList<BufferedReader>(); List<? extends Reader> weirdList2 = new ArrayList<FileReader>(); If Java allows you to add a BufferedReader to weirdList1 , you will also need to add a BufferedReader to weirdList2 (the link type is the same), which is not assumed, since weirdList2 should only store FileReader s.