2 回答

TA貢獻(xiàn)1804條經(jīng)驗(yàn) 獲得超7個(gè)贊
查看字節(jié)碼我們可以看到,該類(lèi)Impl
基本上生成了以下函數(shù):
public?go(I)V
其中參數(shù)是原始整數(shù)。還會(huì)生成一個(gè)合成橋接函數(shù) (?go(Object)
),但它也會(huì)在 Java 端針對(duì)此類(lèi)通用函數(shù)生成。
然而,在 Java 方面,僅僅擁有類(lèi)似的東西是不夠的public void go(int field)
?,F(xiàn)在我們需要那個(gè)go(Integer field)
- 函數(shù),但它不存在。kotlin 編譯器知道如何處理這個(gè)問(wèn)題,并且不需要在類(lèi)文件中提供任何有關(guān)它的進(jìn)一步信息(即實(shí)現(xiàn) Kotlin 類(lèi)知道,它不需要實(shí)現(xiàn)類(lèi)似的東西fun go(field : Int?)
)。對(duì)于 Java 端來(lái)說(shuō),這樣的對(duì)應(yīng)物不存在。我想知道這是否可以通過(guò)編譯器/字節(jié)碼很好地解決,或者這是否仍然是一個(gè)特定的互操作問(wèn)題。
處理該問(wèn)題的一些解決方法(如果這是故意的而不是真正的問(wèn)題):
添加一個(gè)附加函數(shù)如下Impl:
fun go(field : Int?) = go(field ?: error("Actually the given field should never be null"))
// or simply:
fun go(field : Int?) = go(field!!)
這樣您就不需要實(shí)施它。但是,您還會(huì)向 Kotlin 端公開(kāi)該可為 null 的函數(shù),而您可能不希望這樣做。
出于該特定目的,以相反的方式執(zhí)行似乎更方便:在 Java 中聲明類(lèi)和接口并在 Kotlin 端使用它。這樣你仍然可以聲明類(lèi)似的東西
abstract class KotlinClass : JavaInterface<Int> {
? override fun go(field : Int) { // an IDE might suggest you to use Int? here...
? ? // ...
? }
}

TA貢獻(xiàn)1773條經(jīng)驗(yàn) 獲得超3個(gè)贊
您可以使用它javap來(lái)分析問(wèn)題,顯示已編譯的接口和類(lèi)的成員。
javap基礎(chǔ)
public interface Base<T> {
public abstract void go(T);
}
javap 實(shí)現(xiàn)
public abstract class Impl implements Base<java.lang.Integer> {
public void go(int);
public void go(java.lang.Object);
public Impl();
}
所以,問(wèn)題正是@Roland指出的:為了滿足接口請(qǐng)求的契約Base,Java編譯器需要一個(gè)public void go(java.lang.Integer)方法,但Kotlin編譯器生成的方法有int作為參數(shù)。
如果你用 Java 實(shí)現(xiàn)接口,比如
class JI implements Base<Integer> {
@Override
public void go(@NotNull Integer field) {
}
}
javap您可以通過(guò)獲取來(lái)分析其編譯版本
爪哇
class JI implements Base<java.lang.Integer> {
org.amicofragile.learning.kt.JI();
public void go(java.lang.Integer);
public void go(java.lang.Object);
}
因此,如果您打算使用 Kotlin 類(lèi)Impl作為 Java 類(lèi)的超類(lèi),解決方案就是使用<Integer>,而不是<Int>,作為類(lèi)型參數(shù):Int是一個(gè) Kotlin 類(lèi),int由編譯器翻譯為;Integer是您通常在 Java 代碼中使用的 Java 類(lèi)。
將您的示例更改為
abstract class Impl : Base<Integer> {
override fun go(field: Integer) {}
}
public class JavaImpl extends Impl {
}
JavaJavaImpl類(lèi)編譯時(shí)沒(méi)有錯(cuò)誤。
添加回答
舉報(bào)