如何在 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 代码,因为它是二进制库中已编译的 class 文件。
只实现一个以 Int
作为参数的方法,可以从 Kotlin 或 Java.
调用
class B : A {
override fun get(i: Int): Any {
return "something"
}
}
如果你反编译字节码,你会发现 Kotlin 编译器足够聪明,可以创建这两种方法,其中一种只是重定向到真正的实现。
一个可能的问题是您不能使该方法采用 Int?
,如果从 [=31] 调用 .intValue()
,它将因 NullPointerException
而崩溃=] 像这样:
B b = new B();
Integer i = null;
b.get(i);
我不确定是否有办法解决该用例。
编辑: hotkey 的答案包含其余答案。
如果单个实现(如 @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 编译器理解不同类型的可空性注释,here's the list。
在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写了一个简单的demo。
然后在 IntelliJ IDEA 或 Android Studio 中使用 Kotlin 插件将其转换为 Kotlin。
添加这些行以在 kotlin 中实现接口
class abc : AppCompatActivity(), interface 1, interface 2,
{
override fun get(i: Int?): Any
}
既然Kotlin没有原语,这个接口怎么实现?
public interface A {
@NotNull Object get(@NotNull Integer i);
@NotNull Object get(int i);
}
我无法更改 Java 代码,因为它是二进制库中已编译的 class 文件。
只实现一个以 Int
作为参数的方法,可以从 Kotlin 或 Java.
class B : A {
override fun get(i: Int): Any {
return "something"
}
}
如果你反编译字节码,你会发现 Kotlin 编译器足够聪明,可以创建这两种方法,其中一种只是重定向到真正的实现。
一个可能的问题是您不能使该方法采用 Int?
,如果从 [=31] 调用 .intValue()
,它将因 NullPointerException
而崩溃=] 像这样:
B b = new B();
Integer i = null;
b.get(i);
我不确定是否有办法解决该用例。
编辑: hotkey 的答案包含其余答案。
如果单个实现(如 @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 编译器理解不同类型的可空性注释,here's the list。
在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写了一个简单的demo。
然后在 IntelliJ IDEA 或 Android Studio 中使用 Kotlin 插件将其转换为 Kotlin。
添加这些行以在 kotlin 中实现接口
class abc : AppCompatActivity(), interface 1, interface 2,
{
override fun get(i: Int?): Any
}