[英]Java generics: Calling generic Method “…is not applicable for the arguments…”
[英]Java Generics: Method X is not applicable for the arguments
EventHandler.java:
public abstract class EventHandler<E extends EventArgs> {
public abstract void HandleEvent(Object sender, E e);
}
Observers.java:
public class Observers<E extends EventArgs> {
private CopyOnWriteArrayList<EventHandler<? extends E>> mListeners = new CopyOnWriteArrayList<EventHandler<? extends E>>();
public void dispatchEvent(Object sender, E args) {
if (mListeners != null) {
for (EventHandler<? extends E> listener : mListeners) {
listener.HandleEvent(sender, args);
}
}
}
}
以下行:
listener.HandleEvent(sender, args);
原因:
EventHandler类型中的方法HandleEvent(Object,capture#3-of?extends E)不适用于参数(Object,E)
有人怎么解决这个问题?
EDIT1原因? super E
? super E
对我不起作用的是我在Observers
类中有以下方法:
public void addListener(EventHandler<? super E> listener) {
mListeners.add(listener);
}
这导致:
参数类型CopyOnWriteArrayList>中的方法add(EventHandler)不适用于参数(EventHandler)
EDIT2
改变的原因是? super E
因为这个原因, ? super E
到E
对我不起作用: 当X延伸Y时,X不适用于参数Y.
它已经是那样了,但这既不起作用:(
为什么你宣布mListeners
为〜 ? extends E
? extends E
而不仅仅是E
?
如果你使用
private CopyOnWriteArrayList<EventHandler<E>> mListeners = new CopyOnWriteArrayList<EventHandler<E>>();
它会工作的。
或采用PECS(Producer Extends,Consumer Super)。 正如其他人所说
private CopyOnWriteArrayList<EventHandler<? super E>> mListeners = new CopyOnWriteArrayList<EventHandler<? super E>>();
与for
循环相关的更改。
编辑:一个更全面的例子。 这显示没有警告或错误,并且根据您给出的内容,它将起作用。
public static class Sandbox {
public static interface EventArgs {}
public static abstract class EventHandler<E extends EventArgs> {
public abstract void HandleEvent(Object sender, E e);
}
public static class Observers<E extends EventArgs> {
private CopyOnWriteArrayList<EventHandler<? super E>> mListeners
= new CopyOnWriteArrayList<EventHandler<? super E>>();
public void dispatchEvent(Object sender, E args) {
if (mListeners != null) {
for (EventHandler<? super E> listener : mListeners) {
listener.HandleEvent(sender, args);
}
}
}
public void addListener(EventHandler<? super E> listener) {
mListeners.add(listener);
}
}
}
用? super E
? super E
而不是? extends E
? extends E
更改
for (EventHandler<? extends E> listener : mListeners) {
至
for (EventHandler<? super E> listener : mListeners) {
需要进行此更改的原因是该类具有E
的实例。 但是,如果您的侦听器需要E
的子类,则不保证E
满足此合同。 但是,如果侦听器期望基类E
,那么E
保证满足合同。
什么EventHandler<? extends E>
EventHandler<? extends E>
装置是“为一个事件处理程序E
或某种未知子类E
,因此它可能需要一个未知子类的成员,因此它不能与使用E
。
您可能需要做的就是将事件处理程序列表的类型更改为CopyOnWriteArrayList<EventHandler<E>>
。
将观察者更改为:
public static class Observers<E extends EventArgs> {
private CopyOnWriteArrayList<EventHandler<E>> mListeners = new CopyOnWriteArrayList<EventHandler<E>>();
public void dispatchEvent(Object sender, E args) {
if (mListeners != null) {
for (EventHandler<E> listener : mListeners) {
listener.HandleEvent(sender, args);
}
}
}
}
E已经在类定义中定义为扩展EventArgs,它不需要在每次后续使用中重新定义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.