我在以下代码中遇到了一些问题。
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());代码行”返回以下编译错误:
该方法在类型中添加(捕获#1-of?extends IEvent) ArrayList不适用于 参数(GoogleEvent)
班级GoogleEvent
的声明如下:
public class GoogleEvent implements IEvent {...}
我知道在Java中使用泛型有一些棘手的部分,因此是通配符,但我似乎无法弄清楚这一点。
感谢。
答案 0 :(得分:5)
你为什么不写:
public List<IEvent> getEventsByDateRange(DateTime minStartTime, DateTime minEndTime)
{
List<IEvent> returnedEvents = new ArrayList<IEvent>();
returnedEvents.add(new GoogleEvent());
return returnedEvents;
}
答案 1 :(得分:2)
这是不允许的。 returnedEvents
包含GoogleEvent
个对象的列表,不允许接受不是GoogleEvent
个对象的对象。
虽然在您的示例中您恰好传递了GoogleEvent
,但您通过调用add
的版本来接受实现IEvent
的任何内容。不允许调用add
方法,因为它可能导致列表存储GoogleEvent
以外的内容。
Java通配符“编辑”会以这种方式破坏规则的方法。
如果您需要返回该通配符列表类型,ArrayList<GoogleEvent>
可以满足要求。
注意这是一个完整的源文件,可以无错误地编译:
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);
}
}
答案 2 :(得分:2)
您不需要使用? extends IEvent
因为仅使用IEvent
,Java将动态绑定GoogleEvent
类。这是多态性。
答案 3 :(得分:2)
解决方案:
ArrayList<IEvent> returnedEvents = new ArrayList<IEvent>();
出错的原因是编译器正在尝试执行capture conversion。
在您的情况下,returnedEvents
会捕获扩展IEvent
的某些未知(即扩展/实现IEvent
的任何内容),并将其分配给参数化输入GoogleEvent
)。
编译器看到,returnedEvents.add(? extends IEvent)
未使用returnedEvents.add(GoogleEvent)
的签名进行验证,因为在returnedEvents
上设置了捕获占位符。
答案 4 :(得分:0)
public ArrayList<IEvent> getEventsByDateRange(DateTime minStartTime,
DateTime minEndTime)
{
ArrayList<IEvent> returnedEvents = new ArrayList<IEvent>();
returnedEvents.add(new GoogleEvent());
return (returnedEvents);
}
答案 5 :(得分:0)
您无法编写使用? extends ...
声明的变量。只有在使用? super ...
时才允许写作。
这可以通过以下示例解释:
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声明为List<GoogleEvent>
。