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

既然Kotlin没有原始的东西,那怎么能实现呢?

public interface A { Object get(Integer i); Object get(int i); } 

我无法更改Java代码,因为它是库中已编译的类文件。

如果一个实现(比如@ zsmb13的答案)对于你来说是不够的,你需要对Kotlin中的两个方法进行单独的实现,那么你可以添加一个中间接口来覆盖接受Integer的方法的一个可为空的参数:

 private interface IntermediateA : A { override fun get(i: Int?): Any } 

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

 class C : IntermediateA { override fun get(i: Int) = "primitive" override fun get(i: Int?) = "boxed" } 

 val a: A = C() println(a.get(1)) // primitive println(a.get(1 as Int?)) // boxed 

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

 Object get(@Nullable Integer i); 

Kotlin编译器理解不同types的可空性注释, 这里是列表 。

只实现一个以Int为参数的方法,可以从Kotlin或Java中调用。

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

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

反编译的字节码示例

一个可能的问题是,你不能使方法采取Int? ,如果它是从Java调用的,它将在.intValue()调用中发生NullPointerExceptionexception:

 B b = new B(); Integer i = null; b.get(i); 

我不确定是否有办法解决这个用例。

编辑:热键的答案有其余的答案。

在Kotlin,我们可以声明:

原始 int为: Int

盒装诠释: Int?

您的界面可以简化为:

 private interface ModifiedA : A { override fun get(i: Int?): Any } 

在Kotlin中,如果你实现了这个修改后的界面,那么Kotlin会为你提供两种覆盖方法。 一种用于原始types,另一种用于盒装types。

 class ImplementationOfA : ModifiedA { override fun get(i: Int) override fun get(i: Int?) } 

我写了一个简单的演示在Java中。

然后在ideaAndroid Studio使用kotlin插件将其转换为kotlin。