Java通用通配符:如果有什么需要?延伸T,T有什么问题?

时间:2012-07-04 21:39:32

标签: java generics

   protected List<? extends ErrorTO> errors = new ArrayList<ErrorTO>();

    public abstract Collection<? extends ErrorTO> getErrors();

    public void registerError(ErrorTO e) {
        errors.add(e);
    }

有一行“errors.add(e)”的编译错误,它期待某种类型的“?extends ErrorTO”并且不喜欢ErrorTO?为什么和浩来解决这个问题?谢谢!

4 个答案:

答案 0 :(得分:2)

编译器不知道getErrors将返回Collection<ErrorTo>;它可能会返回Collection<SomeSubclassOfErrorTo>。如果您随后尝试将不属于此子类的ErrorTo添加到集合中,则会违反类型安全性。因此,编译器不允许您这样做。

答案 1 :(得分:1)

您无法向List<? extends ErrorTO>添加任何内容。将其设为List<ErrorTO>

List<? extends ErrorTO>表示:一些未知类的列表,它是ErrorTO或扩展ErrorTO。很明显,如果你可以添加一些东西,它的类型安全性就会被打破。

答案 2 :(得分:1)

List<? extends ErrorTO> 一个列表,可以包含任何扩展ErrorTO的内容。

它是ErrorTO的一个(未指定的)子类的列表。

如果MyErrorTO扩展ErrorTO,那么我可以创建List<MyErrorTO>并将其分配给errors

然后您的代码会尝试将ErrorTO添加到我的列表中,这是非法的 - 我的列表只能包含ErrorTO的特定子类

答案 3 :(得分:0)

也许这会有所帮助。让我们说我们有课程

class Fruit {}
class Pear extends Fruit{ void methodA(){} }
class Apple extends Fruit{ void methodB(){} }

我们想创建像这样的方法

public static void method(List<? extends Fruit> list, Fruit f) {
    list.add(f); //<-- why is this forbidden?
}

作为list参数,此方法可以接受像

这样的列表
ArrayList<Fruit>
ArrayList<Apple>
ArrayList<Pear>

如果参数为new ArrayList<Pear>();,则编译器不应允许添加像Fruit或Apple这样的元素。

但编译器无法知道他将要处理的列表类型。由于缺乏知识,不可能通过List<? extends Fruit> list引用添加任何元素。