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

ワイルドカードのないジェネリック パラメーターはバリアントではないため、まったく同じ型 (サブタイプでもスーパー タイプでもない) が必要です。(ソース

コンパイラは、これを許可しません。エラー メッセージが示すように、パラメーターの型パラメーターは 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 メソッドでは、Class<T>ではなくを指定していますClass<EventListener>

于 2012-05-16T17:03:34.407 に答える