Home » Java » Getting "Incompatible types" error when using code generated from a Kotlin data class

Getting "Incompatible types" error when using code generated from a Kotlin data class

Posted by: admin December 28, 2021 Leave a comment

Questions:

If I decompile the .class file generated by data class State(val b: List<Array<Int>>) then I get the following Java code:

public final class State {
    private final List<? extends Integer[]> b;

    public State(List<? extends Integer[]> b) {
      this.b = b;
    }

    public final List<Integer[]> getB() {
      return this.b;
    }

    // ...
}

If I copy/paste this java code into my IDE (Intellij 15), I get the following compilation error in the getB() method:

Incompatible types.

Required: List<Integer[]>
Found:    List<? extends Integer[]>

What am I missing here? How is the Kotlin generated code able to do this but not my copy/pasted version?

Answers:

In general, when javac loads a .class file, it does not perform a complete type check of the code in that class; it will trust the generic signatures specified in the bytecode. Because of that, other JVM languages can generate signatures which javac itself would refuse to generate.

In this specific case, the wildcards generated by Kotlin beta 4 make no sense (Integer[] is a final class, so ? extends Integer[] is useless), so the current development version doesn’t generate any wildcards in this example.

More generally, our goal is to ensure that APIs written in Kotlin are easy to consume from Java code, and in order to achieve this, Kotlin lets you control where exactly it generates wildcards. This is described here under “Java Wildcards”.