5

这段代码:

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

有一个编译错误

List 类型中的方法 add(capture#1-of ? extends Reader) 不适用于参数 (BufferedReader)

为什么?BufferedReader 扩展了阅读器,那为什么不是“匹配”呢?

4

3 回答 3

6

当编译器看到<? extends Reader>时,它假定它可以是任何类型,即是或扩展Reader。它可能是与 不兼容的东西BufferedReader,例如StringReader. 因此,如果类定义中的泛型类型出现在方法的参数中,例如add,并且实例的类型具有类似<? extends Something>的内容,编译器出于类型安全原因必须禁止它。在此示例中,它可能List<StringReader>,因此您不能在BufferedReader此处添加 a。

于 2013-04-02T22:22:52.977 回答
6

List<? extends Reader> weirdList可以保存对List存储任何类型的任何类型的引用Reader。所以有可能

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

如果 Java 允许您添加BufferedReaderweirdList1它也必须让您添加BufferedReaderweirdList2(引用类型相同),这不应该发生,因为weirdList2应该只存储FileReaders。

于 2013-04-02T22:27:41.487 回答
3

对于您提供的变量:

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>.

于 2013-04-02T22:31:09.543 回答