繁体   English   中英

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

[英]How to implement this Java interface in Kotlin?

既然 Kotlin 没有原语,那么这个接口怎么实现呢?

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

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

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

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,我们可以声明:

  • primitive int as: 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编写了一个简单的演示。

然后使用IntelliJ IDEA或Android Studio中的Kotlin插件将其转换为Kotlin。

添加这些行以在 kotlin 中实现接口

class abc : AppCompatActivity(), interface 1, interface 2,
{
override fun get(i: Int?): Any
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM