Java语法

时间:2013-04-02 22:18:39

标签: java generics

此代码:

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

的编译错误为

  

该方法在类型中添加(捕获#1-of?extends Reader)   列表不适用于   arguments(BufferedReader)

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

3 个答案:

答案 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>这样的“裸”通用。