我正在开发一个需要对不同的自定义事件和监听器做出反应的程序。
我试图用泛型来缩短它,事实是,我不明白我的错误在哪里。
这是我的代码:
听众和活动:
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)
我在没有结果的情况下尝试了其他一些事情,我找不到任何与我的代码匹配的解决方案。
有人有任何解决方案或无法解决? 我的目标是让更短的代码成为可能,甚至漂亮。
感谢的
答案 0 :(得分:2)
通常,您只需为每个侦听器类型声明两种方法:
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);
然后,您将需要一个能够查找给定侦听器的相应侦听器类型的方法:
private Class<? extends EventListener> getListenerType(EventListener listener){
for(Class<? extends EventListener> listenerType : SUPPORTED_LISTENER_TYPES){
if(listenerType.isAssignableFrom(listener.getClass())){
return listenerType;
}
}
return null;
}
现在,您可以在addListener
和removeListener
方法中使用此方法:
@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);
}
此处未经检查的强制转换是安全的,因为保证给定的listener
是getListenerType()
返回的类型的后代。
答案 1 :(得分:0)
您无法通过这种方式推荐课程。请改为调用listener.getClass。