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);
}