Java中的通用addListener

时间:2017-02-22 17:03:49

标签: java generics listener

我正在开发一个需要对不同的自定义事件和监听器做出反应的程序。

我试图用泛型来缩短它,事实是,我不明白我的错误在哪里。

这是我的代码:

听众和活动:

public interface MyFirstListener extends EventListener {
    void firstRequest(String text);
}

public interface MySecondListener extends EventListener {
    void secondRequest(String text);
}

public class MyEvent extends EventObject {
    private String text = null;

    public MyEvent(Object source, String text) {
        super(source);
        this.text = text;
    }

    public String getText() {
        return text;
    }
}

这里有棘手的代码:

public class MyProblem {

    private EventListenerList listenerList = new EventListenerList();

    public MyProblem() {}

    public <T extends EventListener> void addListener(T listener) {
        listenerList.add(T.class, listener); // Here I have : Illegal class literal for the type parameter T
    }

    public <T extends EventListener> void removeListener(T listener) {
        listenerList.remove(T.class, listener); // Here I have : Illegal class literal for the type parameter T
    }

    void fireFirstRequestEvent(MyEvent evt) {
        for (MyFirstListener listener : listenerList.getListeners(MyFirstListener.class)) {
            listener.firstRequest(evt.getText());
        }
    }   

    void fireSecondRequestEvent(MyEvent evt) {
        for (MySecondListener listener : listenerList.getListeners(MySecondListener.class)) {
            listener.secondRequest(evt.getText());
        }
    }   

    public static void main(String[] args) {

        FirstClass first = new FirstClass();
        SecondClass second = new SecondClass();

        MyProblem problem = new MyProblem();
        problem.addListener(first);
        problem.addListener(second);
    }
}


class FirstClass implements MyFirstListener {
    @Override
    public void firstRequest(String text) {
        // Do Something
    }
}

class SecondClass implements MySecondListener {
    @Override
    public void secondRequest(String text) {
        // Do Something
    }
}

问题在于方法addListeners和removeListeners,我有这个错误:类型参数T的非法类文字 我无法抓住它。

我也尝试这段代码:

listenerList.add(listener.getClass(), listener); // Here I have : The method add(Class<T>, T) in the type EventListenerList is not applicable for the arguments (Class<capture#1-of ? extends EventListener>, T)

我在没有结果的情况下尝试了其他一些事情,我找不到任何与我的代码匹配的解决方案。

有人有任何解决方案或无法解决? 我的目标是让更短的代码成为可能,甚至漂亮。

感谢的

2 个答案:

答案 0 :(得分:2)

通常,您只需为每个侦听器类型声明两种方法:

public void addFirstListener(MyFirstListener listener) {
    listenerList.add(MyFirstListener.class, listener);
}

public void removeFirstListener(MyFirstListener listener) {
    listenerList.remove(MyFirstListener.class, listener);  
}

如果您希望能够动态添加和删除侦听器,则必须查找应由其运行时类型添加/删除的侦听器类型。

例如,创建支持的侦听器类型列表。在您的示例中,有两种类型MyFirstListener.classMySecondListener.class

private final static List<Class<? extends EventListener>> SUPPORTED_LISTENER_TYPES 
        = Arrays.asList(MyFirstListener.class, MySecondListener.class);

然后,您将需要一个能够查找给定侦听器的相应侦听器类型的方法:

private Class<? extends EventListener> getListenerType(EventListener listener){
    for(Class<? extends EventListener> listenerType : SUPPORTED_LISTENER_TYPES){
        if(listenerType.isAssignableFrom(listener.getClass())){
            return listenerType;
        }
    }
    return null;
}

现在,您可以在addListenerremoveListener方法中使用此方法:

@SuppressWarnings("unchecked")
public void addListener(EventListener listener) {
    if(listener == null){
        return;
    }
    Class<? extends EventListener> listenerType = getListenerType(listener);
    if(listenerType == null){
        throw new IllegalArgumentException("Listener " + listener + " not supported");
    }
    listenerList.add((Class<EventListener>)getListenerType(listener), listener);
}

此处未经检查的强制转换是安全的,因为保证给定的listenergetListenerType()返回的类型的后代。

答案 1 :(得分:0)

您无法通过这种方式推荐课程。请改为调用listener.getClass。