2016-12-14 3 views
2

申し訳ありませんが、貧しいタイトルのために、誰かが良いアイデアを持っている場合は、私は提案に開放されています。宣言からサブタイプを返すJava 8 CompletableFuture

私はCompletableFutureで遊んでいました。私は奇妙なことに遭遇しました。 ABB extends A、そうBAのサブタイプである:

は、あなたが2つのクラスがあるとしましょう。

さて、CompletableFutureを宣言してみましょう:BAのサブタイプであることので、これが機能している

CompletableFuture<A> promiseofA = CompletableFuture.supplyAsync(() -> new B()); 

それはCompletableFutureの宣言に準拠しています。今、私はexceptionallyステップを追加したい場合は、その後、私はコンパイル例外があります。

CompletableFuture<A> promiseOfA = CompletableFuture.supplyAsync(() -> new B()) 
                .exceptionally(ex -> new B()); 

この場合のJavaのことを述べ、不平を言っている:

Compilation error[ java.util.concurrent.CompletableFuture<B> cannot be converted to java.util.concurrent.CompletableFuture<A>] 

は、なぜそれがexcepionallyステップなしで働いていますそしてそれではない?

答えて

6

exceptionallyを追加すると機能しません。これは入力のソースの将来に完全に依存しているためです。

これは、例外的にソースの未来がCompletableFuture<B>であることを確認した場合、返されるタイプはCompletableFuture<B>である必要があります。

ソースが実際にCompletableFuture<A>CompletableFuture.<A>supplyAsync(...))であることを指定すると、正しく再度コンパイルされます。これは、Javaのジェネリック型控除に関する問題です。

+2

を具体的に:それはあなたも行うことができ、サプライヤー関数型の推論である '... supplyAsync((サプライヤー(A)new B()... ' –

0

は、私は非常にしてAを拡張し、ワイルドカードを追加し、コンパイルエラーは消えていた。

CompletableFuture<? extends A> promiseOfA1 = CompletableFuture.supplyAsync(() -> new B()) 
      .exceptionally(ex -> new B()); 
+0

私は 'extend' /'を使用することを勧めません。あなたが 'promiseOfA1'で' exceptionnally() 'を呼び出すことができないようにします。 –

+0

ハム、私の理解から、彼がしていることですそこに ''例外的に() 'を呼んで、いいえ? –

+0

@MartinGOYOTここで私は'promiseOfA1'ではなく' suppliyAsync() 'の結果で呼び出すことができます。これは、その静的型によって防止されます。 –

関連する問題