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?
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".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With