I think I may have run into some edge case regarding platform types annotated with Nullable annotations.
Let’s say that I have some interface A in Java with some default methods, such as:
import org.checkerframework.checker.nullness.qual.Nullable;
public interface A {
default @Nullable Object toObject() {
return null;
}
}
Then, some interface B also in Java with some additional methods, such as:
public interface B {
Object getUnrelated():
setUnrelated(Object value):
}
Notice that while A has chosen to use Nullable annotations, B did not.
When in Kotlin we try implementing from B, we can only implement B’s methods as not null, since otherwise the Kotlin compiler throws an error. It assumes that the return type of B.getUnrelated()
must never be null, and the argument of B.setUnrelated(Object)
the same.
B makes no such statement regarding it’s methods (being nullable or not null).
Example C class in Kotlin that implements from B:
class C: B { // Error: Class 'C' is not abstract and does not implement abstract member 'setUnrelated'.
private var unrelated: Any? = null
override fun getUnrelated(): Any? = unrelated // Error: Return type is 'Any?', which is not a subtype of overridden public abstract fun getUnrelated(): Any defined in B
override fun setUnrelated(value: Any?) { // Error: 'setUnrelated' overrides nothing
unrelated = value
}
}
It appears as though the inferences made about A and it’s methods are carried to B and applied the same, whereas B may not even belong to a module that has chosen to use nullability annotations.
Surely the issue can be fixed by adding annotations to B, but shouldn’t Kotlin make any nullability assumptions regarding the methods declared exclusively by B?
If relevant, I would like to add that this is not some made up, artificial scenario. There is a class in Hibernate called ManagedEntity.
Some of it’s methods are clearly documented as supporting receiving/returning nulls.
However, one cannot create instances of ManagedEntity objects in Kotlin because the super interface of it uses Nullable annotations, hence triggering the issue above.