此代码:
List<? extends Reader> weirdList;
weirdList.add(new BufferedReader(null));
的编译错误为
该方法在类型中添加(捕获#1-of?extends Reader) 列表不适用于 arguments(BufferedReader)
为什么呢? BufferedReader扩展了读者,为什么不是“匹配”?
答案 0 :(得分:6)
当编译器看到<? extends Reader>
时,它会认为它可能是任何类型,或者是Reader
。它可能与BufferedReader
不兼容,例如StringReader
。因此,如果类定义中的泛型类型出现在诸如add
之类的方法的参数中,并且实例的类型具有类似<? extends Something>
的类型,则编译器必须因类型安全原因而不允许它。在此示例中,可能为List<StringReader>
,因此您无法在此处添加BufferedReader
。
答案 1 :(得分:6)
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
。
答案 2 :(得分:3)
对于您提供的变量:
List<? extends Reader> weirdList;
以下所有作业均有效:
weirdList = new ArrayList<Reader>();
weirdList = new ArrayList<FileReader>();
weirdList = new ArrayList<BufferedReader>();
weirdList = new ArrayList<InputStreamReader>();
希望这能解释您的编译错误。如果weirdList
包含ArrayList<BufferedReader>
类型的值,但对ArrayList<FileReader>
类型的值没有意义,那么您尝试的是有意义的。由于类型List<? extends Reader>
的变量可以包含任何一种类型的值(以及更多!),因此Java会调用该错误。
Java中的泛型很难理解。您可以将List<? extends Reader>
类型视为对方法中的赋值或参数类型最有用,以便它们可以接受各种类型。对于“常规使用”,您可能最好使用“{”1}}甚至List<Reader>
这样的“裸”通用。