这段代码:
List<? extends Reader> weirdList;
weirdList.add(new BufferedReader(null));
Run Code Online (Sandbox Code Playgroud)
有一个编译错误
在类型List中添加(捕获#1-of?extends Reader)的方法不适用于参数(BufferedReader)
为什么?BufferedReader扩展了读者,为什么不是"匹配"呢?
当编译器看到时<? extends Reader>,它假定它可以是任何类型或扩展Reader.它可能是与之不相容的东西BufferedReader,例如StringReader.因此,如果类定义中的泛型类型出现在方法的参数中add,并且实例的类型类似<? extends Something>,则编译器必须因类型安全原因而不允许它.在这个例子中,它可能是List<StringReader>,所以你不应该在BufferedReader这里添加.
List<? extends Reader> weirdList可以保存任何类型的List存储任何类型的引用Reader.所以有可能
List<? extends Reader> weirdList1 = new ArrayList<BufferedReader>();
List<? extends Reader> weirdList2 = new ArrayList<FileReader>();
Run Code Online (Sandbox Code Playgroud)
如果你的Java将允许您添加BufferedReader到weirdList1它也将让你加入BufferedReader到weirdList2(引用类型是一样的),这是不是假设发生,因为weirdList2应该只存储FileReader秒.
对于您给出的变量:
List<? extends Reader> weirdList;
Run Code Online (Sandbox Code Playgroud)
以下所有分配均有效:
weirdList = new ArrayList<Reader>();
weirdList = new ArrayList<FileReader>();
weirdList = new ArrayList<BufferedReader>();
weirdList = new ArrayList<InputStreamReader>();
Run Code Online (Sandbox Code Playgroud)
希望这可以解释您的编译错误。weirdList如果持有 type 的值,您尝试的操作是有意义的ArrayList<BufferedReader>,但对于 type 的值则没有意义ArrayList<FileReader>。由于类型变量List<? extends Reader>可以保存任一类型(甚至更多!)的值,因此 Java 称其为错误。
Java 中的泛型很难理解。您可以认为该List<? extends Reader>类型对于方法中的赋值或参数类型最有用,以便它们可以接受多种类型。对于“常规使用”,您可能最好使用“裸”泛型,例如List<Reader>或List<BufferedReader>。