这段代码:
List<? extends Reader> weirdList;
weirdList.add(new BufferedReader(null));
有一个编译错误
List 类型中的方法 add(capture#1-of ? extends Reader) 不适用于参数 (BufferedReader)
为什么?BufferedReader 扩展了阅读器,那为什么不是“匹配”呢?
当编译器看到<? extends Reader>
时,它假定它可以是任何类型,即是或扩展Reader
。它可能是与 不兼容的东西BufferedReader
,例如StringReader
. 因此,如果类定义中的泛型类型出现在方法的参数中,例如add
,并且实例的类型具有类似<? extends Something>
的内容,编译器出于类型安全原因必须禁止它。在此示例中,它可能是List<StringReader>
,因此您不能在BufferedReader
此处添加 a。
List<? extends Reader> weirdList
可以保存对List
存储任何类型的任何类型的引用Reader
。所以有可能
List<? extends Reader> weirdList1 = new ArrayList<BufferedReader>();
List<? extends Reader> weirdList2 = new ArrayList<FileReader>();
如果 Java 允许您添加BufferedReader
到weirdList1
它也必须让您添加BufferedReader
到weirdList2
(引用类型相同),这不应该发生,因为weirdList2
应该只存储FileReader
s。
对于您提供的变量:
List<? extends Reader> weirdList;
以下所有作业均有效:
weirdList = new ArrayList<Reader>();
weirdList = new ArrayList<FileReader>();
weirdList = new ArrayList<BufferedReader>();
weirdList = new ArrayList<InputStreamReader>();
希望这可以解释您的编译错误。如果weirdList
持有 type 的值,您正在尝试的内容是有意义的ArrayList<BufferedReader>
,但对于 type 的值没有意义ArrayList<FileReader>
。由于类型变量List<? extends Reader>
可以保存任何一种类型的值(以及更多!),Java 将其称为错误。
Java 中的泛型很难理解。您可以认为该List<? extends Reader>
类型对方法中的赋值或参数类型最有用,因此它们可以接受多种类型。对于“常规使用”,您可能最好使用“裸”通用,例如List<Reader>
甚至List<BufferedReader>
.