Kotlin SAM运行时错误:NoSuchMethodError:没有静态方法
今天,我开发了一个非常奇怪的运行时错误,同时开发涉及SAM转换和子分类的kotlin / android。
这是一个纯java + kotlin的最简单的例子。 这里有两个java类:
public class A { public interface I { public void f(); } public I i; } public class B extends A {}
这里是一个kotlin的主要功能:
fun main(args: Array<String>) { A().i = BI {} }
此代码编译好,但在运行时,我得到以下错误:
Exception in thread "main" java.lang.NoSuchMethodError: BI(Lkotlin/jvm/functions/Function0;)LA$I; at MainKt.main(Main.kt:2)
现在,这已经很糟糕了 – 如果这样的代码不起作用(我永远不会猜到)编译器应该提出一个错误。 但至少有人可以说,通过子类B
而不是定义A
(即AI
)的位置来引用接口I
是不好的主意。
不太清楚,但是如果这个代码是在B
的子类中,我可以直接使用I
来引用I
:
class C: B { constructor() { this.i = I {} } }
所以我的问题是:
- 为什么这种行为会发生呢?
- 如果正在发生,为什么编译器不会引发错误?
PS:在android中的错误信息看起来类似于这,这是更令人困惑的:
Caused by: java.lang.NoSuchMethodError: No static method OnFocusChangeListener(Lkotlin/jvm/functions/Function2;)Landroid/view/View$OnFocusChangeListener; in class Landroid/widget/LinearLayout; or its super classes (declaration of 'android.widget.LinearLayout' appears in /system/framework/framework.jar:classes2.dex)
将主要方法定义为static-
companion object { @JvmStatic fun main(args: Array<String>) { A().i = BI {} } }