考虑以下Java类:
package javapkg;
public class JavaClass {
private interface JavaInterface {
void foo();
}
public void bar(JavaInterface ji) {
ji.foo();
}
}
Kotlin代码使用此类的内部接口进行SAM转换(请注意KotlinClass
位于不同的包中):
package kotlinpkg
import javapkg.JavaClass
class KotlinClass {
fun f() {
val jc = JavaClass()
// Does not compile:
// "Cannot access 'JavaInterface': it is private in 'JavaClass'"
jc.bar(object : JavaClass.JavaInterface{
override fun foo() { }
})
// Compiles and runs fine on Android Nougat, but throws
// a NoClassDefFoundError exception on Kitkat
jc.bar { }
}
}
现在,如果你将内部JavaInterface
公开,那么Kotlin代码(SAM转换和对象表达式)将在所有平台上正确编译和运行。由于JavaClass
和KotlinClass
位于不同的包中,因此无法编译对象表达式,因为出于同样的原因,我猜测SAM转换因运行时异常而失败。
我的问题:为什么SAM转换成功编译?它似乎不应该因为接口是私有的,更糟糕的是它会导致Kitkat中的运行时异常。此外,对象表达式不编译。这是Kotlin编译器中的错误,还是故意的?