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.