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
所以我在想应该从覆盖的方法中删除可空性还是保留它们?
答案 0 :(得分:8)
此问题的来源来自 Java和Kotlin之间的互操作性。 Java
和Kotlin
之间存在一些基本的语言级别差异,这会导致互操作性问题。 Android Studio提供了一些Lint
检查以警告它们,例如Unknown Nullness
。 (reference)
通过查看android.com的Unknown nullness
棉绒支票的详细信息,我们看到:
要改善
Kotlin
中的引用代码,请考虑添加 此处使用@NonNull
或@Nullable
来显式显示无效信息。
如果您使用
Kotlin
引用在Java
类( eg aString
)中定义的未注释名称成员,则编译器不会知道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的内容,因此可以将其视为 证明其参数应该为不可为空。
答案 3 :(得分:1)
在Java代码中未将它们指定为可为空的注释。
如果是这样,请注意,如果Java代码中未将其指定为可为空的注释,则可能会引发NullPointerException
并分配空值。
因此,如果未在Java代码中指定为可为空的注释,则从覆盖的方法中删除可为空性。
答案 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的互操作性,短绒棉只抱怨在另一个方向上缺少注释。
上的最新文章