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

时间:2017-05-23 10:44:17

标签: java kotlin kotlin-interop

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

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

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

4 个答案:

答案 0 :(得分:14)

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

Integer

实现此接口而不是原始private interface IntermediateA : A { override fun get(i: Int?): Any } ,Kotlin编译器将区分这两种方法,允许您按如下方式覆盖它们:

A

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

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

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

Kotlin编译器理解不同类型的可空性注释here's the list

答案 1 :(得分:7)

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

class B : A {

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

}

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

Decompiled bytecode example

一个可能的问题是,你不能使方法采用Int?,如果从NullPointerException调用.intValue(),它会因B b = new B(); Integer i = null; b.get(i); 调用而崩溃,如下所示:< / p>

function RDetailController($routeParams, Rep) {
    var self = this;
    self.Name = $routeParams.Name;

    Rep.envGetSingle(self.Name).then(function (response) {
      // console.log(response.data.length);
      self.Details = response.data;
      console.log(self.Details);

    });

    Rep.repGetByCurDate(self.Name).then(function(response) {
      // console.log(response.data.length);
      self.report = response.data;
      console.log(self.report);
    });
  }

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

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

答案 2 :(得分:2)

在Kotlin,我们可以声明:

  • 原始 int as:Int
  • 装箱 int as: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?)
}

答案 3 :(得分:0)

我用Java编写了一个简单的演示。

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