簡體   English   中英

返回CompletableFuture <Void>或CompletableFuture <?>?

[英]Return CompletableFuture<Void> or CompletableFuture<?>?

我想編寫一個返回CompletableFuture的異步方法。 未來的唯一目的是追蹤方法何時完成,而不是結果。 返回CompletableFuture<Void>CompletableFuture<?>會更好CompletableFuture<?> 有理由偏愛其中一個,還是可以互換?

請注意,我只詢問返回類型,而不是參數列表,變量聲明或其他上下文。

最好使用CompletableFuture<Void>

根據 Sotirios Delimanolis發現的這個答案Future<?>是一個小的API漏洞。 在Java 6中, submit()方法在內部使用了Future<Object> ,因此其返回類型設置為Future<?> 在Java 7中,實現在內部更改為使用Future<Void> ,但是更改API為時已晚,因此返回值仍為Future<?>

較新的Java API使用Future<Void>CompletableFuture<Void> 這些是我們應該遵循的例子。

返回CompletableFuture <Void>或CompletableFuture <?>會更好嗎?

有理由偏愛其中一個,還是可以互換?

代碼可能會影響三種上下文:

  • 運行時 - 泛型對它沒有任何影響。
  • 編譯 - 我無法想象某種方法會接受Future<Void>但不接受Future<?>
  • 開發 - 如果Future的結果沒有意義,那么通過聲明向用戶說明這一點是一個好習慣。

所以Future<Void>是更優選的。

查看CompletableFuture API,您會發現CompletableFuture<Void>與副作用一起使用無法獲得結果的方法(因為它不存在),例如:

CompletableFuture.runAsync(Runnable runnable);

返回一個CompletableFuture<Object>會讓人感到困惑,因為沒有真正的結果,我們只關心完成。 使用ConsumersRunnables返回CompletableFuture<Void> ,例如: thenAcceptthenAcceptAsync ConsumerRunnable通常用於副作用。

Void另一個用例是當你真的不知道結果時。 例如: CompletableFuture.allOf ,傳遞的列表可能是源自Runnable的CompletableFuture,因此我們無法獲得結果。

說完所有這些, CompletableFuture<Void>只有在你沒有其他選擇的情況下才有用,如果你可以返回結果然后請去它,如果他們不感興趣,調用者可能會選擇丟棄。 你說你只對完成感興趣,然后是的, CompletableFuture<Void>會完成這項工作,但是如果他們知道CompletableFuture<T>是一個選項並且你只是代表他們決定他們的API用戶會討厭你永遠不會需要結果。

合適的類型取決於其語義。 所有列出的選項都承諾信號完成,並可能異步返回異常。

  • CompletableFuture<Void>Void告訴用戶沒有預期的結果。
  • CompletableFuture<?> ? 表示包含值的類型在任何值都可以傳遞的意義上是未定義的。

CompletableFuture類從CompletionStage繼承了幾個便捷方法。 但是它也允許你的方法的調用者觸發未來的完成,這似乎是錯誤的,因為你的方法負責發出它自己的完成信號。 還有一個cancel(...)方法在CompletableFuture的默認實現中毫無意義,因為它不會取消執行。

  • Future<Void>Void告訴用戶沒有預期的結果。
  • Future<?> ? 表示包含值的類型在任何值都可以傳遞的意義上是未定義的。

Future缺乏CompletionStage的便捷方法。 它不允許觸發未來的完成,但可以取消執行。

下一個選項是CompletionStage<Void>

  • CompletionStage<Void>Void告訴用戶沒有預期的結果。 存在綁定處理程序的便捷方法,但cancel(...)方法不存在。 方法的調用者無法觸發CompletionStage
  • <CancellableFuture extends Future<Void> & CompletionStage<Void>> :來自Future<Void>CompletionStage<Void> 它告訴沒有結果,存在便利方法以及取消選項。 方法的調用者無法觸發CompletionStage

缺少cancel(...)方法可能適合您的情況。 因此,如果您不需要取消,我建議使用CompletionStage<Void>如果您需要取消執行選項,請使用<CancellableFuture extends Future<Void> & CompletionStage<Void>> 如果您選擇<CancellableFuture extends Future<Void> & CompletionStage<Void>>您可能想要自己創建一個繼承Future<Void>CompletionStage<Void>的接口作為返回類型而不是直接放置long類型的交集在您的方法聲明中。

您應該避免使用聲明的返回類型CompletableFuture返回,因為調用者可能會觸發將來的完成。 故意這樣做會導致令人困惑的代碼和令人驚訝的掛起,因為不清楚哪個代碼負責觸發完成。 使用上述更受限制的類型之一讓類型系統防止方法調用者觸發意外完成。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM