簡體   English   中英

可選的<t>作為 Java 中的記錄參數</t>

[英]Optional<T> as a Record Parameter in Java

Java 8 中引入的Optional<T>類型主要推薦用於返回類型和結果。 因此,每當我在 class 字段或方法參數中使用它時,都會在 IntelliJ 中收到警告:

Optional<?>用作字段/參數的類型。

但是,當我在規范構造函數中使用Optional<T>作為記錄參數時,我沒有收到此警告:

public record AuthenticationResult(
    boolean isAuthenticated,
    Optional<User> user,
    Optional<String> authorizationHeader)
{ } 

不使用Optional<T>類型作為參數/字段的做法是否不適用於記錄參數,因為該字段將始終作為記錄的自動生成的 getter 方法的返回值訪問?

或者是因為記錄是一個新特性並且這個警告還沒有實現,並且在記錄中使用可選參數與用作方法參數或字段時具有相同的后果?

不會試圖解釋為什么當前版本的 IntelliJ 不會對具有可選字段的記錄發出警告(這是 IDE 開發人員的問題)。

在這篇文章中,我將解決有關使用Optional的推薦做法的問題,特別是 Java 16 記錄。

不使用Optional<T>類型作為參數/字段的做法是否不適用於記錄參數

首先, Optional不打算用作字段類型,因此Optional不實現Serializable請參閱參考資料)。 其次,記錄是數據載體,它們的字段是final的。 因此,如果一條記錄使用空的可選選項進行初始化,它們將在整個時間跨度內保持為空。

可選的使用

以下是@StuartMarks 、Java 和 OpenJDK 開發人員的回答中關於Optional的用途的引述:

Optional主要用途如下:

Optional 旨在為庫方法返回類型提供有限的機制,其中明確需要表示“無結果”,並且使用 null 極有可能導致錯誤。

Optional 的唯一有效用法是從它的起源方法返回它。 調用者應該立即解壓可選的(API 提供了很多方法)。 但是,如果您傳遞可選的 object 並將其存儲在某個地方,那么您所做的並不是一個好習慣。

可選並不意味着

Optional不打算使用:

  • 作為字段類型;
  • 作為方法參數的一種類型;
  • 存儲在Collection中;
  • 或用於執行空檢查 Optional.ofNullable()代替顯式空檢查是一種反模式。

這是@Brian Goetz ,Java Language Architect 回答的引述( Java 8 getters 是否返回可選類型? ):

當然,人們會為所欲為……

例如,您可能永遠不應該將它用於返回結果數組或結果列表的東西; 而是返回一個空數組或列表。 您幾乎不應該將它用作某物的字段方法參數

另外,看看StuartMarks 的這個答案,這里有一個小引述:

class 字段或數據結構中具有Optional被認為是對 API 的濫用 首先,它違背了 Optional 的主要設計目標,如頂部所述。 其次,它沒有增加任何價值。

記錄是不可變數據的透明載體

帶有 Optional 字段的 object 迫使處理它的人始終考慮到通過 getter 獲得的 object 不是一個值,而是可能為空 optional ,如果你盲目地調用get() ,它可能會拋出NoSuchElementException

此外,在 Record 中包含 Optional 類型的字段與 Records 的一般概念相矛盾。

這是JEP 395記錄的定義:

記錄,它們是充當不可變數據的透明載體的類。 記錄可以被認為是名義元組。

帶有可選字段的記錄不再是透明的,因為我們無法通過訪問器方法直接從中獲取值。

由於記錄字段是不可變的,因此將可能為空的選項存儲為記錄屬性是沒有意義的,這與存儲空引用幾乎相同。 因為無法更改記錄中的字段,所以空的可選項將保持為空,並且您的某些元組可能根本不包含有用的數據。

傳遞選項沒有任何優勢,將它們存儲在記錄中以便在以后發現它們不包含實際數據。

相反,您必須在創建記錄之前從現場某處獲得的可選 object 中提取一個(如果存在)。

暫無
暫無

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

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