如何在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代码,则可以通过向接受盒装类型的方法添加一个可为空的注释来解决此问题:
Object get(@Nullable Integer i);
Kotlin编译器理解不同类型的可空性注释, 这里是列表 。
只实现一个以Int
为参数的方法,可以从Kotlin或Java中调用。
class B : A { override fun get(i: Int): Any { return "something" } }
如果你反编译字节码,你会发现Kotlin编译器足够聪明地创建两种方法,其中一个只是重定向到真正的实现。
一个可能的问题是,你不能使方法采取Int?
,如果它是从Java调用的,它将在.intValue()
调用中发生NullPointerException
异常:
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会为你提供两种覆盖方法。 一种用于原始类型,另一种用于盒装类型。
class ImplementationOfA : ModifiedA { override fun get(i: Int) override fun get(i: Int?) }
我写了一个简单的演示在Java中。
然后在idea
或Android Studio
使用kotlin插件将其转换为kotlin。