如何在Kotlin中实现这个Java接口?

ice*_*000 25 java kotlin kotlin-interop

由于Kotlin没有基元,如何实现这个接口呢?

public interface A {
  @NotNull Object get(@NotNull Integer i);
  @NotNull Object get(int i);
}
Run Code Online (Sandbox Code Playgroud)

我无法更改Java代码,因为它是二进制库中的编译类文件.

hot*_*key 19

如果@ zsmb13的答案中的单个实现对您来说还不够,并且您需要在Kotlin中对这两个方法进行单独的实现,那么您可以添加一个中间接口来覆盖接受Integer可以为null的参数的方法:

private interface IntermediateA : A {
    override fun get(i: Int?): Any
}
Run Code Online (Sandbox Code Playgroud)

实现此接口而不是原始接口A,Kotlin编译器将区分这两种方法,允许您按如下方式覆盖它们:

class C : IntermediateA {
    override fun get(i: Int) = "primitive"
    override fun get(i: Int?) = "boxed"
}
Run Code Online (Sandbox Code Playgroud)

val a: A = C()
println(a.get(1)) // primitive
println(a.get(1 as Int?)) // boxed
Run Code Online (Sandbox Code Playgroud)

如果您有权访问Java代码,则可以通过向接受盒装类型的方法添加可空性注释来解决此问题:

Object get(@Nullable Integer i);
Run Code Online (Sandbox Code Playgroud)

Kotlin编译器理解不同类型的可空性注释,这是列表.


zsm*_*b13 7

实现只有一个方法可以Int作为参数工作,并且可以从Kotlin或Java调用.

class B : A {

    override fun get(i: Int): Any {
        return "something"
    }

}
Run Code Online (Sandbox Code Playgroud)

如果你反编译字节码,你会发现Kotlin编译器足够聪明,可以创建两种方法,其中一种方法只是重定向到真正的实现.

反编译的字节码示例

一个可能的问题是你不能使方法占用Int?,并且如果从Java调用它就会NullPointerException.intValue()调用时崩溃:

B b = new B();
Integer i = null;
b.get(i);
Run Code Online (Sandbox Code Playgroud)

我不确定是否有办法解决该用例.

编辑:热键的答案中有其余的答案.