32

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

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

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

4

5 回答 5

25

如果单个实现(如@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 编译器理解不同类型的可空性注释,这里是列表

于 2017-05-23T11:44:25.897 回答
11

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

class B : A {

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

}

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

反编译的字节码示例

一个可能的问题是你不能让方法 take ,如果它是从 Java 调用的,它会在调用Int?时崩溃,如下所示:NullPointerException.intValue()

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

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

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

于 2017-05-23T10:50:18.027 回答
4

在 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?)
}
于 2017-05-23T16:26:48.677 回答
0

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

class abc : AppCompatActivity(), interface 1, interface 2,
{
override fun get(i: Int?): Any
}
于 2021-11-30T13:00:40.743 回答
0

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

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

于 2017-09-07T08:48:26.060 回答