使用从 Kotlin 数据 class 生成的代码时出现 "Incompatible types" 错误
Getting "Incompatible types" error when using code generated from a Kotlin data class
如果我反编译 data class State(val b: List<Array<Int>>)
生成的 .class 文件,那么我会得到以下 Java 代码:
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;
}
// ...
}
如果我 copy/paste 这个 java 代码进入我的 IDE (Intellij 15),我在 getB()
方法中得到以下编译错误:
Incompatible types.
Required: List<Integer[]>
Found: List<? extends Integer[]>
我在这里错过了什么? Kotlin 生成的代码如何能够执行此操作而不是我的 copy/pasted 版本?
一般来说,当javac加载一个.class文件时,它不会对该class中的代码进行完整的类型检查;它将信任字节码中指定的通用签名。因此,其他 JVM 语言可以生成 javac 本身拒绝生成的签名。
在这种特定情况下,Kotlin beta 4 生成的通配符没有意义(Integer[]
是最终的 class,所以 ? extends Integer[]
没有用),所以当前的开发版本在此示例中不生成任何通配符。
更一般地说,我们的目标是确保用 Kotlin 编写的 API 易于从 Java 代码中使用,为了实现这一点,Kotlin 允许您控制它生成通配符的确切位置。 "Java Wildcards".
下描述了 here
如果我反编译 data class State(val b: List<Array<Int>>)
生成的 .class 文件,那么我会得到以下 Java 代码:
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;
}
// ...
}
如果我 copy/paste 这个 java 代码进入我的 IDE (Intellij 15),我在 getB()
方法中得到以下编译错误:
Incompatible types.
Required: List<Integer[]>
Found: List<? extends Integer[]>
我在这里错过了什么? Kotlin 生成的代码如何能够执行此操作而不是我的 copy/pasted 版本?
一般来说,当javac加载一个.class文件时,它不会对该class中的代码进行完整的类型检查;它将信任字节码中指定的通用签名。因此,其他 JVM 语言可以生成 javac 本身拒绝生成的签名。
在这种特定情况下,Kotlin beta 4 生成的通配符没有意义(Integer[]
是最终的 class,所以 ? extends Integer[]
没有用),所以当前的开发版本在此示例中不生成任何通配符。
更一般地说,我们的目标是确保用 Kotlin 编写的 API 易于从 Java 代码中使用,为了实现这一点,Kotlin 允许您控制它生成通配符的确切位置。 "Java Wildcards".
下描述了 here