Generics, nullability and default signatures


#1

I am concerned with the changes to the default kotlin signatures for methods with generics in M5.

Let’s consider the following java method:

String[] something(String[] arr)

Before M5, the kotlin signature was this:

fun something(arr: Array<String?>?): Array<String?>?

And this was a problem because if you had an Array<String> in kotlin, you couldn’t pass it to this method directly, and had to convert it to an Array<String?> first.

As I understand it, with M5, the kotlin signature has become this:

fun something(arr: Array<String>?): Array<String>?

And now we can pass it our Array<String> directly without conversion. If we really want to pass it an Array<String?>, we can change the signature with annotations.

I am ok with the change for the type of the parameter arr, but not with the return type.

With the current situation, every time we use a method from java that returns an array, we have to be really sure that it never has null, or we better annotate it.
If we don’t the code will break. But it will only break in those cases where it does return an array with a null value, which might only be in very specific cases, so
we might not catch the problem. And if we are using libraries, we might have checked the code once and noticed that it was ok without annotation, and
then we update the lib and it’s no longer the case. When upgrading a lib, it’s a lot easier to check our custom annotations and make sure they are still valid,
than recheck all the code to find where this might have become a problem.

We’ve gained a bit by not having to convert our arrays, but we’ve lost a lot of safety with this.
The cool thing about before is we could decide if we wanted to ignore null values or not by using !! or ?. calls on the array values.
Now we lose this unless we go add custom annotations everywhere.

I think the idea was good, it just needs to apply only to parameters and not return types.


#2

First of all, there are very few APIs that use arrays and even fewer that use collections that contain nulls. It's OK to annotate them.

I think of it this way: if you used pure Java, nobody would warn you about any nulls, in Kotlin you can get your nulls right once you hit a problem: by introducing the annotation. It is a big win.