13

次のインターフェイスが与えられた場合、

 public interface Callback<T> {
    <K, V> T execute(Operation<K, V> operation) throws SomeException;
 }

operationタイプがである新しい匿名クラスにインターフェイスを実装するにはどうすればよいですか?Operation<String,String>

たとえば、これはコンパイルされません:

 Callback<Boolean> callback = new Callback<Boolean>() {
        @Override
        public Boolean execute(Operation<String, String> operation) {
              return true;
        }
 };
 executor.execute(callback);
4

2 に答える 2

11

メソッドのジェネリックは、クラスのジェネリックパラメーターとは無関係です。

あなたはそれが正しいためにメソッドでそれらを繰り返す必要があります、例えば

Callback<Boolean> callback = new Callback<Boolean>() {
        @Override
        public <X,Y> Boolean execute(Operation<X, Y> operation) {

        }
};
executor.execute(callback);

つまり、インターフェイスには、任意の操作パラメーターで機能する実行メソッドが必要です。

特定のパラメータでのみ機能するコールバックが必要な場合は、それらをクラスシグネチャの一部にする必要があります。

 public interface Callback<T,K,V> {
    T execute(Operation<K, V> operation) throws SomeException;
 }

それはあなたにできるでしょう

Callback<Boolean,String,String> callback = new Callback<Boolean,String,String>() {
        @Override
        public Boolean execute(Operation<String, String> operation) {

        }
};
executor.execute(callback);

私はあなたが望むものを手に入れるためのルートを見ることができません...あなたがあなたを制限しすぎるかもしれない<? super K,? super V>またはフォームを使い始めない限り。<? extends K,? extends V>

これがあなたのインターフェースが消去するものです

 public interface Callback<T> {
    T execute(Operation<Object, Object> operation) throws SomeException;
 }

次に、インスタンス化するとT == Boolean

 public interface Callback {
    Boolean execute(Operation<Object, Object> operation) throws SomeException;
 }

これは、

    Boolean execute(Operation<String, String> operation) throws SomeException;

inパラメータが狭いのでメソッド。パラメータを広げたり、パラメータを絞り込んだりすることはできますが、その逆はできません。

これが、リターンタイプ( outパラメータ)をからObjectに変更できる理由を説明しています。BooleanObjectBoolean

ClassCastException逆に、メソッドを呼び出して結果に基づいて動作する人にを与えるため、戻り値のタイプを広げることはできません。

(パラメーター内の)メソッド引数は、拡張することしかできません。Javaはさまざまなタイプをさまざまなメソッドと見なすため、メソッド引数はやや複雑になります。

public interface Callback<T> {
  T execute(Object key, Object value);
}

Callback<Boolean> cb = new Callback<Boolean> {
  @Override
  public Boolean execute(Object k, Object v) { ... }
  // not an @Override
  public Boolean execute(String k, String v) { ... }
}

2番目のメソッドのシグネチャが異なるためです。しかし、あなたのクラスは、それがまたはであるかOperation<X,Y>どうかに関係なく、生のタイプだけに消去されますOperation<String,String>Operation<X,Y>

できることが1つあります...しかし、それは厄介になります!

public interface StringOperation extends Operation<String,String> {}

その後、あなたはすることができます

Callback<Boolean> cb = new Callback<Boolean> {
  @Override
  public <K,V> Boolean execute(Operation<K,V> o) { ... }
  // not an @Override
  public Boolean execute(StringOperation o) { ... }
}

ただし、execute(Callback<?>)メソッドは呼び出し<K,V> Boolean execute(Operation<K,V> o)であり、ではないことに注意してくださいBoolean execute(StringOperation o)

于 2012-10-10T14:20:38.273 に答える
5

クラス名のtypeパラメーターとメソッドのtypeパラメーターは実際には異なるため、以下で実行できます。

   @Override
    public <K, V> Boolean execute(Operation<K, V> operation)
            throws SomeException {
        return false;
    }
于 2012-10-10T14:13:46.833 に答える