Generic: ArrayList of ? Extends ISomeInterface in Java
我在下面的代码中遇到了一些问题。
1 2 3 4 5 6 | public ArrayList<? extends IEvent> getEventsByDateRange(DateTime minStartTime, DateTime minEndTime) { ArrayList<? extends IEvent> returnedEvents = new ArrayList<GoogleEvent>(); returnedEvents.add(new GoogleEvent()); return (returnedEvents); } |
这会为"returnedEvents.add(new GoogleEvent()); line of code"返回以下编译错误:
The method add(capture#1-of ? extends IEvent) in the type
ArrayList is not applicable for the
arguments (GoogleEvent)
类
1 | public class GoogleEvent implements IEvent {...} |
我知道在 Java 中使用泛型有一些棘手的部分,因此是通配符,但我似乎无法弄清楚这一点。
谢谢。
你为什么不写:
1 2 3 4 5 6 | public List<IEvent> getEventsByDateRange(DateTime minStartTime, DateTime minEndTime) { List<IEvent> returnedEvents = new ArrayList<IEvent>(); returnedEvents.add(new GoogleEvent()); return returnedEvents; } |
解决办法:
1 | ArrayList<IEvent> returnedEvents = new ArrayList<IEvent>(); |
您的错误原因是因为编译器正在尝试进行捕获转换。
在您的情况下,
编译器看到,
您不需要使用
这是不允许的。
虽然在您的示例中您恰好传递了一个
以外的内容
Java 通配符"编辑出"方法会以这种方式破坏规则。
如果你需要返回那个通配符列表类型,一个
注意这是一个完整的源文件,编译时不会出错:
1 2 3 4 5 6 7 8 9 10 11 12 13 | import java.util.*; interface IEvent { } class GoogleEvent implements IEvent { } public class Foo { public ArrayList<? extends IEvent> getEventsByDateRange() { ArrayList<GoogleEvent> returnedEvents = new ArrayList<GoogleEvent>(); returnedEvents.add(new GoogleEvent()); return (returnedEvents); } } |
你不能写入一个用
时才允许写入
这可以用下面的例子来解释:
1 2 3 4 5 6 7 8 9 | List<GoogleEvent> googleEvents = new ArrayList<GoogleEvent>(); ArrayList<? extends IEvent> returnedEvents = googleEvents; // Would be OK returnedEvents.add(new GooleEvent()); // Would be OK to the definition of returnedEvents, // but breaks the googleEvents. returnedEvents.add(new OtherEvent()); |
您的简短解决方案是将 returnedEvents 声明为
1 2 3 4 5 6 7 | public ArrayList<IEvent> getEventsByDateRange(DateTime minStartTime, DateTime minEndTime) { ArrayList<IEvent> returnedEvents = new ArrayList<IEvent>(); returnedEvents.add(new GoogleEvent()); return (returnedEvents); } |