2017-02-02 3 views
0

私は(java.util.function.Functionとしてはかなり同じ)エラーといくつかのパラメータ化サブインターフェイスについてユーザーに尋ねるための一般的な機能のインタフェースを持っている:ジェネリック型が機能的なインタフェースであることをjavaに伝えるには?

@FunctionalInterface 
public interface Handler<Err,Resp> { 
    public Resp handle(Err param); 
} 
@FunctionalInterface 
public interface RecoverableErrorHandler<Err> extends Handler<Err, RecoverableErrorResult > {} 

@FunctionalInterface 
public interface RetryIgnoreErrorHandler<Err> extends Handler<Err, RetryIgnoreAbortResult> {} 

私は別のものにハンドラをラップすることにより、各ハンドラへのロギングを追加しますハンドラ:

private <Err,Resp,H1 extends Handler<Err,Resp> > H1 addLogToHandler(String s, H1 h) { 
    return (Err arg) -> { 
     Resp res = h.handle(arg); 
     logger.info(s+" returned "+res); 
     return res; 
    }; 
} 

// some code omitted 
RecoverableErrorHandler<String> netErrorHandler = ... // shows dialog and asks user what to do 
netErrorHandler = addLogToHandler("Network Error handler", netErrorHandler); 

これはreturnとライン上error: incompatible types: H1 is not a functional interfaceでコンパイルされません。

質問は、私は汎用的なH1が機能的なインターフェイスであることをjavaに伝えることができますか?または、このコードをどうやって動作させるのですか?

+3

に方法を変更することができます。戻り値の型はジェネリックパラメータ 'H1'です。実際の型を知らずに 'H1'のインスタンスを作成するにはどうすればいいですか? –

+0

関数が引数と必要な戻り値型によって呼び出される場所でjava型を推論しませんか?私の例では、 '' netErrorHandler = addLogToHandler( "Network Error handler"、netErrorHandler);で '' H1のタイプは '' RecoverableErrorHandler ' –

+1

でなければなりません。基本的に 'public T method(){return new Dog();}'を実行しようとしています。どのようにこれまでに動作する予定ですか?もしこのメソッドを呼び出してジェネリック型の引数として 'Cat'を使用したいのであれば? –

答えて

2

H1は機能的なインターフェイスであるはずですが、実際にはH1がインターフェイスであるとも言えません。

H1Handler<Err,Resp>に拡張する機能インターフェイスに制限できたとしても、このタイプにはコード内のラムダ式と互換性のある関数型があるという保証はありませんでした。

例えば、以下の制約を満たすタイプであろう:

@FunctionalInterface 
public interface Foo<E,R> extends Handler<E,R>, Runnable { 
    default R handle(E param) { run(); return null; } 
} 

これは、機能インタフェースであり、それはHandlerを拡張するが、(Err) -> Resp署名とaddLogToHandler内にそれを実装しようとすると、動作しないことができます。

解決策は簡単です。サブインターフェイスRecoverableErrorHandler<Err>RetryIgnoreErrorHandler<Err>を完全に削除してください。彼らはHandler<Err,RecoverableErrorResult> respを使用することより利点を提供しません。 Handler<Err,RetryIgnoreAbortResult>

サブタイプを排除したら、これは意味がありません

private <Err,Resp> Handler<Err,Resp> addLogToHandler(String s, Handler<Err,Resp> h) { 
    return arg -> { 
     Resp res = h.handle(arg); 
     logger.info(s+" returned "+res); 
     return res; 
    }; 
} 
+0

ありがとうございます。これは私が最後にやったことです。 –

関連する問題