java - 我應該刪除繼承類中未用nullable註釋的重寫方法的可空性嗎




android kotlin (4)

Android 3.5.1

我使用的是WebView,我注意到當我重寫某些方法時,所有參數都是可為null的類型:

webview.webViewClient = object : WebViewClient() {
    override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
         return super.shouldOverrideUrlLoading(view, request)
    }
}

這意味著我必須使用 safe call 運營商來使用它們。 但是,當我查看已覆蓋該方法的 WebViewClient 類時,未在Java代碼中將其指定為 nullablenullable 註釋。

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
    return shouldOverrideUrlLoading(view, request.getUrl().toString());
}

因此,我想到了要從重寫方法中刪除可空性還是保留它們?


在Java代碼中,未將它們指定為可為空的註釋。

如果是這樣,請注意,如果Java代碼中未將其指定為可為空的註釋,則可能會引發 NullPointerException 並分配空值。 因此,如果未在Java代碼中指定為可空註釋,則從覆蓋的方法中刪除可空性。

有關更多詳細信息,請閱讀 kotlinlang.org


在語言級別上,可以將其概括為:

為了實現適當的Java互操作性,Kotlin代碼應反映Java代碼的註釋。

對於Kotlin的互操作性,短絨棉只抱怨在另一個方向上缺少註釋。

請參閱有關 如何編寫Java友好的Kotlin代碼的 最新文章


此問題的來源來自 Java和Kotlin之間的互操作性 JavaKotlin 之間存在一些基本的語言級別差異,這會導致互操作性問題。 Android Studio提供了一些 Lint 檢查來警告它們,例如 Unknown Nullness 。 ( reference


通過查看來自 android.com Unknown nullness Lint檢查的詳細信息,我們看到:

為了改善 Kotlin 引用代碼,請考慮在此處使用 @NonNull@Nullable 添加顯式的null信息。


並在 developer.android.com

如果使用 Kotlin 引用 Java 類中定義的未註釋名稱成員( 例如 String ),則編譯器不知道 String 映射為 String 還是 String?Kotlin 。 這種歧義性通過 平台類型 String!


並在 kotlinlang.org

Java 任何引用都可能為 null ,這使得 Kotlin 對來自 Java 對象的嚴格的null安全性要求不切實際。 Java 聲明的類型在 Kotlin 中被特別對待,稱為 平台類型


因此,當我們覆蓋 Java 方法的參數未使用null註釋進行註釋時,IDE將為 Kotlin 類中的參數添加可為空的符號( ? )。 通過在其中一個參數中傳遞 null 值, 可以避免 Java 調用該方法時引發 NullPointerException

webview.webViewClient = object : WebViewClient() {
    override fun shouldOverrideUrlLoading(
        view: WebView, // <- potential to throw NPE before executing the function block!
        request: WebResourceRequest // <- as well!
    ): Boolean {
        return super.shouldOverrideUrlLoading(view, request)
    }
}


簡而言之,我們 不應該 刪除 ? Java 類中定義重寫的方法時,從函數參數中進行符號簽名。


空引用現在對於每個人來說都是非常明顯的例外,因為對於任何事情,都是從C / C ++的本機開發開始的。 對內存中對象的引用可能由於各種原因而丟失或清除。 Java是使用這些本機語言設計的,這些本機語言 在所有地方都假定為空指針。

使用數千種微服務,管理所有可變狀態變得越來越有趣。 這導致了很多可空引用的解決方法。 - Optional 對象- Null Object 模擬-引用周圍的 Wrappers - Annotations 等。所有這些都是為了避免更改已分配對象的狀態。

最後,科特林不在這裡。 具有不變狀態的Scala在使用和支持應用程序方面擁有出色的經驗。 因此,回答此問題並總結 Java是從其父C ++以此方式設計的,您應該在各處都期望使用null值。 由於這個原因,我們仍然檢查引用是否為null,即使它沒有被註釋為 @Nullable 。 並且以相同的方式Kotlin處理Java用法,這就是為什麼您需要在覆蓋的方法中處理null值。





nullable