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 {} } } 

所以我的问题是:

  1. 为什么这种行为会发生呢?
  2. 如果正在发生,为什么编译器不会引发错误?

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 {} } }