簡體   English   中英

@NonNull和@Nullable的正確用法是什么?

[英]What are the correct uses of @NonNull and @Nullable?

我對這些注釋的正確使用感到困惑。

android.support.annotation.NonNull;
android.support.annotation.Nullable;

@NonNull文檔中的信息說:

表示參數,字段或方法返回值永遠不能為空。

在參數的情況下,這意味着什么,什么都沒有阻止你傳遞null

例如,假設我有一個MyObject類,並且一個實例可能有也可能沒有標題。

public final class MyObject {

    private String title = null;

    public void setTitle(String title) {
        if (title == null)
            throw new NullPointerException();
        this.title = title;
    }

    public void clearTitle() {
        title = null;
    }
}

這里我使用null來表示缺少標題,但這是一個實現細節,所以我不想要一個方法來設置和清除標題。

如果我將字段title標記為@Nullable ,android studio告訴我setTitle的參數也應該標記為@Nullable (但這與我想要的相反)。

如果我將setTitle方法的參數標記為@NonNull我會收到警告條件title == null始終為false

在這種情況下,這些注釋的正確用法是什么? 如果@NonNull意味着一個參數永遠不能null是錯誤的,用它來表示不應該null 如果是,是否有正確的方法來表明這一點?

@Nonnull@Nullable是聲明性的。 這是對軟件開發人員的暗示。 你告訴他們,參數可以是空值,也可以不是。

如果使用@Nonnull注釋標記參數,則告訴每個使用API​​的人,他們不應在此處傳遞空值,否則他們必須處理后果(例如NullPointerException )。

您可以使用它來聲明,參數SHOULD不應該為null,這是一個有效的用例,在我看來。

關鍵是這個注釋是某種契約,所以如果你正確地宣布你的方法,你就不需要進行檢查。 Android Studio會檢查您是否不熟悉它。 您仍然可以忽略它,但這會導致編譯器警告。

如果省略那些無用的(通過合同)安全檢查,它將正確地拋出nullpointerexceptions。 但開發人員收到了您的注釋警告。

如果您標記參數@NonNull,那么您的方法的用戶需要進行空檢查,因為@NonNull不會在運行時捕獲NPE。 因此,例如,如果你有一個帶有輔助方法的實用程序類在執行之前檢查null,那么你會將這些參數標記為@Nullable,因為你在技術上可以傳遞一個空值,但是可以安全地檢查它。

繼續將參數標記為setTitle方法為@NonNull

這將確保編譯器在某些代碼調用setTitle可能為null的值時發出錯誤。 因此編譯器確保從不使用null調用setTitle 因此,您可以刪除方法中的null檢查,使'title == null始終為false'警告消失。

即你的代碼看起來像這樣:

public final class MyObject {

    private String title = null;

    public void setTitle(@NonNull String title) {
        this.title = title;
    }

    public void clearTitle() {
        title = null;
    }
}

(注意:我沒有使用Android Studio,但我猜它的行為與Eclipse類似。在Eclipse中我得到一個錯誤Null type mismatch: required '@NonNull String' but the provided value is null(/inferred as @Nullable)將null或表達式傳遞給setTitle可能為null。)

順便說一句:用@Nullable注釋字段title的定義會使它更明確, title也可能包含null值。

暫無
暫無

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

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