繁体   English   中英

Java Generics:方法X不适用于参数

[英]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 EE对我不起作用: 当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.

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