Search code examples
kotlinkotlin-interop

How to handle nullable generics with Java interop


I have a Java class that is out of my control, defined as:

public @interface ValueSource {
    String[] strings() default {}
}

I am trying to use this class from a Kotlin file I control, like so:

class Thing {
    @ValueSource(string = ["non-null", null])
    fun performAction(value: String?) {
        // Do stuff
    }
}

I get a compiler error

Kotlin: Type inference failed. Expected type mismatch: inferred type is Array<String?> but Array<String> was expected.

I understand why the inferred type is Array<String?>, but why is the expected type not the same? Why is Kotlin interpreting the Java generic as String! rather than String?? And finally, is there a way to suppress the error?

Kotlin 1.2.61


Solution

  • This isn't a Kotlin issue - this code isn't valid either, because Java simply doesn't allow null values in annotation parameters:

    public class Thing {
    
        @ValueSource(strings = {"non-null", null}) // Error: Attribute value must be constant
        void performAction(String value) {
            // Do stuff
        }
    
    }
    

    See this article and this question for more discussion on this.