简体   繁体   中英

<? extends > Java syntax

This code:

List<? extends Reader> weirdList;
weirdList.add(new BufferedReader(null));

has a compile error of

The method add(capture#1-of ? extends Reader) in the type List is not applicable for the arguments (BufferedReader)

Why? BufferedReader extends reader, so why isn't that a "match"?

When the compiler sees <? extends Reader> <? extends Reader> , then it assumes that it could be any type that is or extends Reader . It could be something that is imcompatible with BufferedReader , such as StringReader . So if the generic type in the class definition shows up in the parameter of a method such as add , and the type of the instance has something like <? extends Something> <? extends Something> , the compiler must disallow it for type safety reasons. In this example, it could be List<StringReader> , so you shouldn't be able to add a BufferedReader here.

List<? extends Reader> weirdList List<? extends Reader> weirdList can hold reference to any type of List that stores any type of Reader . So it is possible that

List<? extends Reader> weirdList1 = new ArrayList<BufferedReader>();
List<? extends Reader> weirdList2 = new ArrayList<FileReader>();

If Java would allow you to add BufferedReader to weirdList1 it would also have to let you add BufferedReader to weirdList2 (reference type is the same) which is not suppose to happen since weirdList2 should store only FileReader s.

For the variable you gave:

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>();

Hopefully this explains your compile error. What you're trying makes sense if weirdList holds a value of type ArrayList<BufferedReader> , but doesn't make sense for a value of type ArrayList<FileReader> . Since a variable of type List<? extends Reader> List<? extends Reader> can hold a value of either type (and more!), Java calls that an error.

Generics in Java are hard to get your head around. You can think of the List<? extends Reader> List<? extends Reader> type as being mostly useful for assignment or parameter types in methods so that they can accept a wide variety of types. For "regular use", you're probably better off with a "bare" generic like List<Reader> or even List<BufferedReader> .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM