Kotlinにはプリミティブがないため、このインターフェイスをどのように実装できますか?
public interface A {
@NotNull Object get(@NotNull Integer i);
@NotNull Object get(int i);
}
Javaコードはバイナリライブラリのコンパイル済みクラスファイルなので変更できません。
@ zsmb1 の答えのような単一の実装では不十分であり、Kotlinの2つのメソッドに個別の実装が必要な場合は、Integer
を受け入れるメソッドをオーバーライドする中間インターフェイスを追加できます。ヌル可能パラメーター:
private interface IntermediateA : A {
override fun get(i: Int?): Any
}
元のA
の代わりにこのインターフェイスを実装すると、Kotlinコンパイラーは2つのメソッドを区別し、次のようにオーバーライドできます。
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コードにアクセスできる場合、ボックス化された型を受け入れるメソッドにnullabilityアノテーションを追加することでこれを修正できます。
Object get(@Nullable Integer i);
Kotlinコンパイラは、さまざまな種類のnullabilityアノテーション ここにリストがあります を理解します。
パラメーターとして機能するInt
を取り、KotlinまたはJavaから呼び出すことができるメソッドを1つだけ実装します。
class B : A {
override fun get(i: Int): Any {
return "something"
}
}
バイトコードを逆コンパイルすると、Kotlinコンパイラーが両方のメソッドを作成するのに十分賢く、そのうちの1つが実際の実装にリダイレクトするだけであることがわかります。
考えられる問題の1つは、メソッドがInt?
を取ることができないことです。Javaから呼び出された場合、.intValue()
呼び出しでNullPointerException
でクラッシュします。そう:
B b = new B();
Integer i = null;
b.get(i);
そのユースケースを解決する方法があるかどうかはわかりません。
編集:ホットキーの回答には、残りの回答が含まれています。
Kotlinでは、以下を宣言できます。
Int
Int?
インターフェイスは次のように簡素化できます。
private interface ModifiedA : A {
override fun get(i: Int?): Any
}
Kotlinでは、この変更されたインターフェイスを実装すると、Kotlinはオーバーライドする2つのメソッドを提供します。 1つはプリミティブ型用で、もう1つはボックス型用です。
class ImplementationOfA : ModifiedA {
override fun get(i: Int)
override fun get(i: Int?)
}
Javaで簡単なデモを作成します。
intelliJのKotlinプラグインを使用してKotlinに変換しますIDEAまたはAndroid Studio。