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

新手上路,请多包涵

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

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

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

原文由 ice1000 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 561
2 个回答

如果 @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 编译器理解不同类型的可空性注释, 列表如下

原文由 hotkey 发布,翻译遵循 CC BY-SA 3.0 许可协议

仅实现一种方法,该方法采用 Int 作为其参数,并且可以从 Kotlin 或 Java 调用。

 class B : A {

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

}

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

反编译字节码示例

一个可能的问题是您不能使该方法采用 Int? ,并且它会崩溃并在 NullPointerException 上调用 .intValue() 如果它像 Java 一样调用所以:

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

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

编辑: 热键的答案中包含其余答案。

原文由 zsmb13 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题