Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I override a java method, and change the nullability of a parameter?

I'm overriding a method from a Java library, and the parameter for the function is annotated as @NonNull. However, when the method is called, the parameter frequently comes in with a null value. When I override the method in Kotlin, it forces me to respect the @NonNull annotation and mark the parameter as not nullable. Of course, Kotlin throws an exception at run time when the parameter comes in with a null value. Is there some way I can override the method in Kotlin and ignore the @NonNull annotation?

Specifically, I'm using the appcompat library for Android. The method is in AppCompatActivity.java

@CallSuper
public void onSupportActionModeFinished(@NonNull ActionMode mode) {
}

The override in Kotlin:

override fun onSupportActionModeFinished(mode: ActionMode) {
    super.onSupportActionModeFinished(mode)
}
like image 569
brain Avatar asked Mar 31 '16 20:03

brain


1 Answers

There seems to be no straightforward way to suppress nullability annotation handling by Kotlin compiler.

As a workaround, you can make an intermediate derived class with @Nullable annotation in Java: when Kotlin compiler sees both @Nullable and @NonNull on the same code element it behaves as if there were no nullability annotations. Then just subclass it in Kotlin. Example:

Consider a class with a @NonNull parameter in Java:

abstract class Base {
    public abstract void f(@NonNull String str);
    //...
}

Kotlin understands the annotation: f(str: String), the type is non-null.

Now extend Base in Java, override the method and add @Nullable annotation to the parameter in Intermediate:

abstract class Intermediate extends Base {
    @Override
    public abstract void f(@Nullable String str);
}

For Intermediate, Kotlin sees f(str: String!), the parameter has platform type, that is, its nullability is unknown.

After that, you will be able to declare nullable parameter in a Kotlin subclass of Intermediate:

class Derived(): Intermediate() {
    override fun f(url: String?) { ... }
}
like image 163
hotkey Avatar answered Oct 06 '22 23:10

hotkey