通用: ArrayList 的 ?在 Java 中扩展 ISomeInterface
我在以下代码中遇到一些问题。
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()); 代码行”的以下编译错误:
类型中的方法add(capture#1-of ? extends IEvent) ArrayList 不适用于 参数(GoogleEvent)
类 GoogleEvent
的声明如下:
public class GoogleEvent implements IEvent {...}
我知道在 Java 中使用泛型有一些棘手的部分,因此使用通配符,但我似乎无法弄清楚这一点。
谢谢。
I'm having some trouble in the following code.
public ArrayList<? extends IEvent> getEventsByDateRange(DateTime minStartTime, DateTime minEndTime)
{
ArrayList<? extends IEvent> returnedEvents = new ArrayList<GoogleEvent>();
returnedEvents.add(new GoogleEvent());
return (returnedEvents);
}
This return the following compilation error for the "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)
The declaration of the class GoogleEvent
is as follows:
public class GoogleEvent implements IEvent {...}
I know there are some tricky parts using generics in Java, thus the wild-cards but I can't seem to figure this out.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
你为什么不写:
Why don't you write:
您不需要使用
吗?扩展 IEvent
因为仅使用IEvent
,Java 将动态绑定GoogleEvent
类。这就是多态性。You don't need to use
? extends IEvent
because by using onlyIEvent
, Java will dynamically bind theGoogleEvent
class. It's polymorphism.解决方案:
错误的原因是编译器正在尝试执行 捕获转化。
在您的情况下,
returnedEvents
捕获了一些扩展IEvent
的未知(即扩展/实现IEvent
的任何内容),并且您'重新将其分配给参数化类型GoogleEvent
)。编译器发现,
returnedEvents.add(? extends IEvent)
未使用returnedEvents.add(GoogleEvent)
签名进行验证,因为在返回事件
。The solution:
The reason of your error is because the compiler is trying to do capture conversion.
In your case
returnedEvents
captures some unknown that extendsIEvent
(i.e. anything that extends/implementsIEvent
) and you're assigning it to a parameterized typeGoogleEvent
).The compiler sees,
returnedEvents.add(? extends IEvent)
which doesn't validate with a signature ofreturnedEvents.add(GoogleEvent)
as the capture placeholder is set onreturnedEvents
.这是不允许的。
returnedEvents
包含GoogleEvent
对象列表,并且不得接受非GoogleEvent
对象的对象。尽管在您的示例中您碰巧传递了
GoogleEvent
,但您是通过调用接受任何实现IEvent
的add
版本来实现这一目的的。根本不允许调用该add
方法,因为它可能会导致列表存储GoogleEvent
以外的内容。Java 通配符“编辑掉”会以这种方式违反规则的方法。
如果您需要返回通配符列表类型,
ArrayList
就可以满足它。注意这是一个完整的源文件,编译不会出错:
This is not allowed.
returnedEvents
contains a list ofGoogleEvent
objects and must not be allowed to accept objects that are notGoogleEvent
objects.Although in your example you happen to be passing a
GoogleEvent
, you are doing so by calling a version ofadd
that accepts anything that implementsIEvent
. Thatadd
method simply isn't allowed to be called, because it could result in the list storing things other thanGoogleEvent
.Java wildcards "edit out" methods that would break the rules in this way.
If you need to return that wildcarded list type, an
ArrayList<GoogleEvent>
satisfies it fine.Note this is a complete source file that compiles without error:
您无法写入使用
声明的变量吗?扩展...
。仅当使用时才允许写入?超级...
。这可以通过以下示例进行解释:
最简单的解决方案是将 returnedEvents 声明为
List
。You cannot writer to a variable which is declared with
? extends ...
. Writing is only allowed when using? super ...
.This can be explained by the following example:
The short solution for you is to declare returnedEvents as
List<GoogleEvent>
.