如何在 Kotlin 中实现这个 Java 接口?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44132574/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to implement this Java interface in Kotlin?
提问by ice1000
Since Kotlin doesn't have primitives, how could this interface be implemented?
既然 Kotlin 没有原语,那么这个接口怎么实现呢?
public interface A {
@NotNull Object get(@NotNull Integer i);
@NotNull Object get(int i);
}
I cannot change the Java code since it's a compiled class file in a binary library.
我无法更改 Java 代码,因为它是二进制库中的编译类文件。
采纳答案by hotkey
If a single implementation, as in @zsmb13's answer, is not enough for you and you need separate implementations for the two methods in Kotlin, then you can add an intermediate interface overriding the method accepting Integer
with a nullable parameter:
如果单个实现(如@zsmb13的答案)对您来说还不够,并且您需要在 Kotlin 中为这两个方法单独实现,那么您可以添加一个中间接口来覆盖Integer
使用可为空参数接受的方法:
private interface IntermediateA : A {
override fun get(i: Int?): Any
}
Implementing this interface instead of the original A
, the Kotlin compiler will distinguish the two methods, allowing you to override them as follows:
实现这个接口而不是原来的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
If you had access to the Java code, you could fix this by adding a nullability annotation to the method accepting the boxed type:
如果您有权访问 Java 代码,则可以通过向接受装箱类型的方法添加可空性注释来解决此问题:
Object get(@Nullable Integer i);
The Kotlin compiler understands different kinds of nullability annotations, here's the list.
Kotlin 编译器理解不同类型的可空性注释,这里是列表。
回答by zsmb13
Implementing just one method that takes Int
as its parameter works, and can be called from either Kotlin or Java.
只实现一种将Int
其作为参数的方法即可工作,并且可以从 Kotlin 或 Java 调用。
class B : A {
override fun get(i: Int): Any {
return "something"
}
}
If you decompile the bytecode, you'll see that the Kotlin compiler is smart enough to create both methods, with one of them just redirecting to the real implementation.
如果你反编译字节码,你会发现 Kotlin 编译器足够聪明,可以创建这两种方法,其中一个只是重定向到真正的实现。
One possible problem is that you can't make the method take Int?
, and it will crash with a NullPointerException
on the .intValue()
call if it's called from Java like so:
一个可能的问题是你不能让方法 take Int?
,如果它是从 Java 调用的,它会NullPointerException
在.intValue()
调用时崩溃,如下所示:
B b = new B();
Integer i = null;
b.get(i);
I'm not sure if there's a way to solve for that use case.
我不确定是否有办法解决该用例。
Edit:hotkey's answer has rest of the answers in it.
编辑:热键的答案包含其余的答案。
回答by Avijit Karmakar
In Kotlin, we can declare:
在 Kotlin 中,我们可以声明:
- primitiveint as :
Int
- boxedint as :
Int?
- 原始int 为:
Int
- 装箱int 为:
Int?
Your interface can be simplified to:
您的界面可以简化为:
private interface ModifiedA : A {
override fun get(i: Int?): Any
}
In Kotlin, if you implement this modified interface then Kotlin will provide you two methods to override. One for primitive type and another one for boxed type.
在 Kotlin 中,如果你实现了这个修改后的接口,那么 Kotlin 将提供两种方法来覆盖。一种用于原始类型,另一种用于盒装类型。
class ImplementationOfA : ModifiedA {
override fun get(i: Int)
override fun get(i: Int?)
}
回答by dong sheng
I write a simple demo in Java.
我用Java编写了一个简单的演示。
then convert it to Kotlin with Kotlin plugins in IntelliJ IDEA or Android Studio.
然后使用 IntelliJ IDEA 或 Android Studio 中的 Kotlin 插件将其转换为 Kotlin。