2

引数を持つインターフェイスExecutorのインスタンスを呼び出すクラスがあります。IService<T>KeyList<T>

   class Executor{
      KeyList<?> _keys;
      IService<?> _service;
      public Executor(IService<?> service, KeyList<?> keys){
         _service = service;
         _keys = keys;
      }

      public void execute(){
         _service.invoke(_keys);
      }
   }

   interface IService<T>{
      public void invoke( KeyList<T> keys);
   }

   class KeyList<T> {
      List<T> _list;
   }

<?>IService と KeyList がどのようにパラメーター化されているかは気にしないため、Executor のメンバーに使用しましたが、次の例では引数が適用できないというコンパイル エラーが発生します。

 public void execute(){
    _service.invoke(_keys); //error on invoke
 }

KeyList<?>が と等しくないので文句を言っていると思いますKeyList<T><?>、 と同じな<? extends Object>ので、少し混乱しています。より良い代替手段はありますか?

4

2 に答える 2

3

ワイルドカード( ) は、特定の?不明なタイプを表します。しかし、ここでは 2 つの別々のワイルドカードを扱っています - それらは同じではないかもしれません。代わりに次を使用します。

class Executor<T> {
    KeyList<T> _keys;
    IService<T> _service;
    public Executor(IService<T> service, KeyList<T> keys){
        _service = service;
        _keys = keys;
    }

    public void execute(){
        _service.invoke(_keys);
    }
}

Tこれは、 classの型パラメーターを宣言し、それをandExecutorの型引数として使用して、互換性を確保します。_keys_service

をパラメータ化できない場合はExecutor、パラメータ化されたヘルパー クラスを使用してみてください。

class Executor {

    private static final class ServiceAndKeys<T> {

        private final KeyList<T> keys;
        private final IService<T> service;

        ServiceAndKeys(IService<T> service, KeyList<T> keys) {
            this.service = service;
            this.keys = keys;
        }

        void execute() {
            service.invoke(keys);
        }
    }

    private final ServiceAndKeys<?> serviceAndKeys;

    public <T> Executor(IService<T> service, KeyList<T> keys){
        serviceAndKeys = new ServiceAndKeys<T>(service, keys);
    }

    public void execute() {
        serviceAndKeys.execute();
    }
}
于 2013-11-03T01:52:48.237 に答える
2

最終的に割り当てるとき

IService<?> _service;

何らかの型になります。これを と考えてくださいtype-1

最終的に割り当てるとき

KeyList<?> _keys;

何らかの型になります。これを と考えてくださいtype-2

これらの型に互換性があるとは何も言っていないため、コンパイラはそれを許可しません。これはCapture Conversionに関係しています。

Ti が形式 ? のワイルドカード型引数 (§4.5.1) である場合、Si は新しい型変数であり、上限は Ui[A1:=S1,...,An:=Sn] であり、下限はnull 型 (§4.1)。

したがって、それぞれ<?>が異なる型の変数です。

醜い解決策は、単純にワイルドカード型宣言を完全に削除することです

KeyList _keys;
IService _service;

ただし、実行時に他の問題が発生する可能性があります。

于 2013-11-03T01:50:52.380 に答える