0

我不明白为什么编译器不接受这段代码

import javax.swing.event.EventListenerList;

import java.util.EventListener;


public class GenericEventsManager {

   EventListenerList listeners = new EventListenerList();


   public <T extends EventListener> void addListener(T listener) {
      listeners.add(listener.getClass(), listener);
   }
}

我得到的错误是

The method add(Class<T>, T) in the type EventListenerList is not applicable for the arguments (Class<capture#1-of ? extends EventListener>, T)

addListener 中的参数是扩展 EventListener 的类型,因此 listener.getClass() 返回Class<? extends EventListener>,这正是 EventListenerList.add 方法所期望的

有人可以解释一下吗?我有一种感觉,它与 getClass() 在编译时没有被解决有关,但对我来说仍然没有意义

4

2 回答 2

2

没有通配符的通用参数不是变体,因此需要完全相同的类型(不是子类型,不是超类型)。(来源

编译器根本不会让你这样做。正如错误信息所暗示的那样,参数上的类型Class参数必须与第二个参数的类型完全相同,这在上面的代码中是不正确的。


他们怎么可能不一样?

因为返回类型listener.getClass()Class<? extends EventListener>,不是Class<T>。你可以——但我不建议这样做——将返回的值Class转换为编译:

listeners.add((Class<T>)listener.getClass(), listener);

这样做时您会收到编译器警告:

Type safety: Unchecked cast from Class<capture#1-of ? extends EventListener> to Class<T>

因为这不是(类型)安全的演员表。


造成这种情况的根本原因可能(我真的不确定)只是EventListenerList#add(). 通常在这种情况下使用PECS;可能有一个add()没有通配符的充分理由。

于 2012-05-16T17:08:56.343 回答
0

是的,但是在您的 add 方法中,您指定的是 a Class<T>,而不是 aClass<EventListener>

于 2012-05-16T17:03:34.407 回答