繁体   English   中英

Java匿名通用继承

[英]Java anonymous generic inheritance

看看下一个代码:

ArrayList<? extends Object> list = new ArrayList<Object>();
list.add(new Object());

它不编译。 问题是为什么?

ArrayList<? extends Object>

和刚刚一样

ArrayList<?>

并且您可以将任何 ArrayList分配给此类型的变量。 例如,

ArrayList<? extends Object> list = new ArrayList<String>();

是合法的。 显然,语言语义不允许您将Object添加到这样的列表中。 事实上,他们不会让你添加任何东西 ,除了null ,或者你直接从列表中检索的东西。

正如Lukas在评论中所指出的那样,甚至将列表自己的项目添加回它也是微不足道的:您需要一个帮助方法来将通配符捕获到命名类型中。

public static void main(String[] args) {
  ArrayList<? extends Object> list = new ArrayList<String>();
  addOwn(list);
}
static <T> void addOwn(List<T> l) { l.add(l.get(0)); }

我认为原因是因为泛型类型不是多态的 当你使用wildcards ? 使用扩展,您无法在集合中添加除null之外的任何内容。

这是一个例子,如果允许的话会发生什么:

Class Car{

}
class A extends Car {

}
class B extends Car{

}

现在你有List<? extends Car> List<? extends Car>

public void someMethod(List<? extends Car> list){
list.add(new A()); //this is not valid
}

你也可以调用这样的方法:

List<B> someList = new Array:list<B>(); 
somemethod(someList);

问题是Foo extends Object并不意味着Collection<Foo>可以被视为Collection<Object>的子类型。 这只是因为前一课不允许你做后者所做的一切; 例如,您无法将Object添加到Collection<Foo> 使用泛型而不是一些具体的类Foo不会改变这一点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM