Kotlin SAM运行时错误:NoSuchMethodError:没有静态方法

时间:2017-06-28 18:03:49

标签: kotlin

今天我在开发涉及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 = B.I {}
}

此代码编译正常,但在运行时我收到以下错误:

Exception in thread "main" java.lang.NoSuchMethodError: B.I(Lkotlin/jvm/functions/Function0;)LA$I;
        at MainKt.main(Main.kt:2)

现在,这已经很糟糕 - 如果像这样的代码不起作用(我猜不会),编译器应该引发错误。但至少有一个人可能会说通过子类I而不是定义B(即A)来引用接口A.I是个坏主意。

但不太清楚,如果此代码位于B的子类中,我可以使用I直接引用I

class C: B {
    constructor() {
        this.i = I {}
    }
}

所以我的问题是:

  1. 为什么会发生这种情况?
  2. 如果发生这种情况,为什么编译器不会引发错误?
  3. 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)
    

1 个答案:

答案 0 :(得分:0)

将main方法定义为static like-

public static async Task<ProductWithBool> GetProductByIdAsync(string id)
        {
            HttpClient client = new HttpClient();

            client.BaseAddress = new Uri("http://eshop.ApiUpdatercentrum.tumam.cz/api/byznys/");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            Product product = null;
            HttpResponseMessage response = await client.GetAsync("GetProduct?code=" + id);

            if (response.IsSuccessStatusCode)
            {
                product = await response.Content.ReadAsAsync<Product>();
            }
            else
            {
                ErrorManager.AddError("Getting product failed");
                return new ProductWithBool(null, 2);
            }
            if (product == null)
            {
                ErrorManager.AddError("Product not found");
                return new ProductWithBool(null, 1);
            }
            return new ProductWithBool(product, 0);
        }