Java中的通用addListener

Java中的通用addListener,java,generics,listener,Java,Generics,Listener,我正在开发一个需要对不同自定义事件和侦听器做出反应的程序 我试图用泛型把它缩短,事实是,我不明白我的错误在哪里 这是我的代码: 侦听器和事件: 下面是棘手的代码: 公共类MyProblem{ 私有EventListenerList listenerList=新的EventListenerList(); 公共MyProblem(){} 公共void addListener(T listener){ add(T.class,listener);//这里有:类型参数T的非法类文本 } 公共void r

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

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

这是我的代码:

侦听器和事件:

下面是棘手的代码:

公共类MyProblem{
私有EventListenerList listenerList=新的EventListenerList();
公共MyProblem(){}
公共void addListener(T listener){
add(T.class,listener);//这里有:类型参数T的非法类文本
}
公共void removeListener(T listener){
remove(T.class,listener);//这里有:类型参数T的非法类文本
}
作废fireFirstRequestEvent(MyEvent evt){
for(MyFirstListener侦听器:listenerList.getListeners(MyFirstListener.class)){
listener.firstRequest(evt.getText());
}
}   
作废fireSecondRequestEvent(MyEvent evt){
for(MySecondListener侦听器:listenerList.getListeners(MySecondListener.class)){
secondRequest(evt.getText());
}
}   
公共静态void main(字符串[]args){
FirstClass first=新的FirstClass();
SecondClass second=新的SecondClass();
MyProblem=新的MyProblem();
问题。addListener(第一个);
问题。addListener(第二个);
}
}
类FirstClass实现MyFirstListener{
@凌驾
公共void firstRequest(字符串文本){
//做点什么
}
}
类SecondClass实现MySecondListener{
@凌驾
公共void secondRequest(字符串文本){
//做点什么
}
}
问题在于addListeners和RemovelListeners方法中,我有一个错误:类型参数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)
listenerList.add(listener.getClass(),listener);//这里我有:类型EventListenerList中的add(Class,T)方法不适用于参数(Class,T)
我尝试了其他一些没有结果的东西,但我没有找到任何与我的代码匹配的解决方案

有人有解决办法吗?或者是无法解决的? 我的目标是让代码尽可能短,甚至漂亮


谢谢

你不能这样介绍一门课。改为调用listener.getClass

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

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

public void removeFirstListener(MyFirstListener listener) {
    listenerList.remove(MyFirstListener.class, listener);  
}
如果希望能够动态添加和删除侦听器,则必须查找应按其运行时类型添加/删除的侦听器类型

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

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

此处未选中的强制转换是安全的,因为给定的
侦听器
保证是由
getListenerType()

返回的类型的后代,从而防止您在运行时使用
T.class
。您的
EventListenerList
看起来如何(尤其是添加和删除方法)?@Calculator它可能看起来像。您是否尝试强制转换listener.getClass的结果?像listenerList.add((Class)listener.getClass(),listener)。您将收到一个警告,但代码应该是正确的。@Calculator是的,它是javax.swing.event.EventListenerList;getClass()既不会返回MyFirstListener.class,也不会返回MySecondListener.class。是的,你是对的。在您回答之后,我尝试使用@Dominik的解决方案编写代码,但是getClass()返回给我FirstClass.class或SecondClass.class,但不是接口类型(FirstListener.class和SecondListener.class)。然后,我将对每种类型的addListener实现正常的方法。另一种获得相同结果的方法是这种实现,但不太通用:`public void addListener(T listener){if(listener instanceof MyFirstListener){listenerList.add(MyFirstListener.class,(MyFirstListener)listener);}否则如果(MySecondListener的侦听器实例){listenerList.add(MySecondListener.class,(MySecondListener)listener);}else{System.err.println(“错误的侦听器”);}`
public void addFirstListener(MyFirstListener listener) {
    listenerList.add(MyFirstListener.class, listener);
}

public void removeFirstListener(MyFirstListener listener) {
    listenerList.remove(MyFirstListener.class, listener);  
}
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;
}
@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);
}