我应该删除继承类中未用nullable注释的重写方法的nullability

时间:2019-10-15 15:21:37

标签: java android kotlin nullable

double

我使用的是WebView,我注意到当我重写某些方法时,所有参数都是可空类型:

Android 3.5.1

这意味着我必须使用webview.webViewClient = object : WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean { return super.shouldOverrideUrlLoading(view, request) } } 运算符来使用它们。但是,当我查看了safe call类时,在Java代码中没有将它们重写为方法,因此未将它们指定为WebViewClient注释。

nullable

所以我在想应该从覆盖的方法中删除可空性还是保留它们?

6 个答案:

答案 0 :(得分:8)

此问题的来源来自 Java和Kotlin之间的互操作性JavaKotlin之间存在一些基本的语言级别差异,这会导致互操作性问题。 Android Studio提供了一些Lint检查以警告它们,例如Unknown Nullness。 (reference


enter image description here

通过查看android.comUnknown nullness棉绒支票的详细信息,我们看到:

  

要改善Kotlin中的引用代码,请考虑添加   此处使用@NonNull@Nullable来显式显示无效信息。


并在developer.android.com上:

  

如果您使用Kotlin引用在Java类( eg a String)中定义的未注释名称成员,则编译器不会知道String是映射到String中的String?还是Kotlin。这种模糊性由平台类型 String!表示。


并在kotlinlang.org上:

  

Java中的任何引用都可能为 null ,这使得Kotlin对来自Java的对象的严格null安全性的要求不切实际。 Java声明的类型在Kotlin中得到特殊对待,并称为平台类型


因此,当我们重写Java方法时,其参数未使用无效注释进行注释时,IDE会为?类中的参数添加可为空的符号(Kotlin)。通过为其中一个参数传递一个NullPointerException值,在Java中调用该方法时,会导致避免抛出 null

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 符号。

答案 1 :(得分:2)

与Kotlin不同,Java对象默认情况下可以接受空值

@Nullable 批注仅用于代码分析器之类的操作(例如,如果在方法内部未处理@Nullable参数,则会显示警告)

@NonNull 批注用于指定接收到的值不能为空

if(@NonNull){
      can omit ? check
}else if(@Nullable){
     Mandatory to put ? check
}else(No annotation){
     Not mandatory but put on safer side .
     Passing null from Java into Kotlin fun without ? will lead to NPE
    if(putting ? check){
     java equivalent Kotlin param  (@Nullable Webview view)
    } else{
     java equivalent Kotlin param (@NonNull Webview view)
    }

}

也请参考:https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#null-safety

答案 2 :(得分:2)

如果Java中的虚拟方法未以某种方式指定其参数的可空性,例如带有@Nullable / @NotNull批注,则在覆盖该方法时,可以随意选择可空性。科特林。

但是您应该选择如何

  • 首先,您可以查阅方法文档并检查方法合同。它是否指定可以用null调用该方法,并且这些null传递给该方法时意味着什么?

    在这种情况下, WebViewClient.shouldOverrideUrlLoading 方法文档页面没有说明任何有关null的内容,因此可以将其视为 证明其参数应该为不可为空

  • 第二,如果您在咨询文档后仍不确定是否可以为空,则可以考虑对空参数值(如果收到)进行处理。如果在这种情况下唯一合理的事情是引发异常,则可以通过将参数声明为不可为空,将该检查委托给Kotlin生成的参数检查代码。

答案 3 :(得分:1)

  

在Java代码中未将它们指定为可为空的注释。

如果是这样,请注意,如果Java代码中未将其指定为可为空的注释,则可能会引发NullPointerException并分配空值。 因此,如果未在Java代码中指定为可为空的注释,则从覆盖的方法中删除可为空性。

有关更多详细信息,请另外阅读this this

答案 4 :(得分:1)

空引用现在对于每个人来说都是非常明显的例外,因为对于所有内容,都是从C / C ++的本机开发开始的。对内存中对象的引用可能由于各种原因而丢失或清除。 Java是用那些本地语言设计的,在所有地方都假定为空指针。

管理所有可变状态正与数千种微服务一起变得有趣。 这会导致为Nullable引用提供很多解决方法。-对象{-Optional的模拟-引用周围的Null Object-Wrappers等所有这些都是为了避免更改某处已分配对象的状态。

最后,科特林不在这里。具有不变状态的Scala在使用和支持应用程序方面拥有出色的经验。 所以回答这个问题并进行总结 Java是通过其父C ++以此方式设计的,您应该在所有地方都期望使用null值。由于这个原因,我们仍然检查引用是否为null,即使没有注释Annotations也是如此。并且以相同的方式Kotlin处理Java用法,这就是为什么您需要在覆盖的方法中处理null值。

答案 5 :(得分:1)

在语言级别上,可以概括为:

  

为了获得适当的Java互操作性,Kotlin代码应反映Java代码的注释。

对于Kotlin的互操作性,短绒棉只抱怨在另一个方向上缺少注释。

请参见How to write Java friendly Kotlin code?

上的最新文章