Android 3.5.1
I was using the WebView and I noticed that when I override some of the methods all the parameters are nullable types:
webview.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
return super.shouldOverrideUrlLoading(view, request)
}
}
Which means I have to use the safe call
operator to use them. However, when I looked at the WebViewClient
class that I have overridden the method from they are not specified as nullable
annotation in the Java code.
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
return shouldOverrideUrlLoading(view, request.getUrl().toString());
}
So I am left thinking do I remove the nullability from the overridden method or keep them?
The source of this issue comes from Interoperability between Java and Kotlin. There are some basic language level differences between Java
and Kotlin
which causes interoperability issues. Android Studio provides some Lint
checks to warn them, such as Unknown Nullness
. (reference)
By taking a look at details of Unknown nullness
Lint check from android.com, we see that:
To improve referencing code from
Kotlin
, consider adding explicit nullness information here with either@NonNull
or@Nullable
.
and on developer.android.com:
If you use
Kotlin
to reference an unannotated name member that is defined in aJava
class (e.g. aString
), the compiler doesn't know whether theString
maps to aString
or aString?
inKotlin
. This ambiguity is represented via a platform type,String!
.
and on kotlinlang.org:
Any reference in
Java
may be null, which makesKotlin
's requirements of strict null-safety impractical for objects coming fromJava
. Types ofJava
declarations are treated specially inKotlin
and called platform types.
Therefore, when we override a Java
method that its arguments are not annotated with nullity annotations, the IDE adds nullable sign (?
) for arguments in Kotlin
class. It leads to avoid throwing NullPointerException
when the method is called in Java
by passing a null
value for one of the arguments.
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)
}
}
In a nutshell, we SHOULD NOT remove ?
sign from function arguments, when the overridden method is defined in a Java
class.
Unlike Kotlin , Java objects by default can accept null values
@Nullable annotation is just used for operations like code analysers (for eg. if the @Nullable parameter is not handled inside the method then it will show warning)
@NonNull annotation is used to specify that the value received can't/won't be null
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)
}
}
Also Refer this : https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#null-safety
If a virtual method in Java doesn't specify nullability of its parameters somehow, for example with the @Nullable
/@NotNull
annotations, you are free to choose the nullability either way when overriding that method in Kotlin.
But how should you choose?
First, you can consult the method documentation and check the method contract. Does it specify that the method can be called with nulls, and what would these nulls mean when passed to the method?
In this particular case, WebViewClient.shouldOverrideUrlLoading method doc page doesn't say anything about nulls, so it can be taken as an evidence that its parameters are supposed to be non-nullable.
They are not specified as nullable annotation in the Java code.
If that's true note that you risk throwing a NullPointerException
if not specified as nullable annotation in the Java code and assign a null value.
so remove the nullability from the overridden method if not specified as nullable annotation in the Java code.
For more detail read this also this
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With