2017-06-28 17 views
5

Bugün SAM dönüşümleri ve alt sınıflama içeren kotlin/android geliştirirken gerçekten garip bir çalışma zamanı hatasıyla karşılaştım.Kotlin SAM Çalışma Zamanı Hatası: NoSuchMethodError: Hayır statik yöntem

İşte saf java + kotlin'in minimal bir örneği. Burada

public class A { 
    public interface I { 
     public void f(); 
    } 

    public I i; 
} 

public class B extends A {} 

Ve KOTLIN ana işlevi olan:

fun main(args: Array<String>) { 
    A().i = B.I {} 
} 

Bu kod iyi derler ama çalışma zamanında aşağıdaki hatayı alıyorum: Artık

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

İşte iki java sınıfları vardır Bu zaten kötü - eğer böyle bir kod işe yaramazsa (asla tahmin edemeyeceğim) derleyici bir hata vermelidir. Ama en azından bir tanesi, A tanımının (A.I) yerine B alt sınıfı aracılığıyla I arayüzüne başvurmanın kötü bir fikir olduğunu söyleyebilirdi.

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

Yani benim sorular olacaktır:

  1. Bu neden olan bu kodun doğrudan I kullanarak ben I başvurabilir B bir alt sınıfında ise

    O, ancak daha az açıktır davranış hiç oluyor mu?
  2. Oluyorsa, derleyici neden bir hata oluşturmuyor?

Not: Bu `tanıdığını önyüz görünüyor

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) 
+2

gibi- statik ana yöntem tanımlayın: android olarak hata mesajı daha da kafa karıştırıcı olan şuna benzer BI {} ', parantez dışında lambda argümanı ile bir işlev çağrısı olarak. Bahse girerim başarısız olan varsayımların bir sonucudur. Verifier (veya adı ne olursa olsun), "B.I", JLS'yi (alt türler aracılığıyla başvurulan süper tip statik üyelere izin ver) izleyen bir ad kayıt defterinde geçerli bir SAM arabirimini gösterir. İsim sistemi JLS'yi takip etmeyen derleyici arka ucu (çünkü kotlin durağan değildir), ancak “B.java” içinde * B * ifadesi bulunmadı, bu yüzden bir işlev çağrısı olmasını bekler. Bu sadece bir rastgele tahmin olsa da. – glee8e

+1

Tahmininin sonucu: derleyici ön ve arka uçları, alt türler aracılığıyla referans verilen süper tip statik üyelere izin verilip verilmediğine * ilişkin farklı politikalara sahiptir *. [Kotlin youtrack] 'da bir sorun bildirmelisiniz (https://youtrack.jetbrains.com/issues/KT). – glee8e

+1

https://youtrack.jetbrains.com/issue/KT-18745 – dpoetzsch

cevap

0

companion object { 
    @JvmStatic fun main(args: Array<String>) { 
     A().i = B.I {} 
    } 
} 
+0

Bu sorunumu çözmüyor – dpoetzsch

İlgili konular