web-dev-qa-db-ja.com

これを実装する方法Java Kotlinのインターフェース?

Kotlinにはプリミティブがないため、このインターフェイスをどのように実装できますか?

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

Javaコードはバイナリライブラリのコンパイル済みクラスファイルなので変更できません。

16
ice1000

@ 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アノテーション ここにリストがあります を理解します。

14
hotkey

パラメーターとして機能するIntを取り、KotlinまたはJavaから呼び出すことができるメソッドを1つだけ実装します。

class B : A {

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

}

バイトコードを逆コンパイルすると、Kotlinコンパイラーが両方のメソッドを作成するのに十分賢く、そのうちの1つが実際の実装にリダイレクトするだけであることがわかります。

Decompiled bytecode example

考えられる問題の1つは、メソッドがInt?を取ることができないことです。Javaから呼び出された場合、.intValue()呼び出しでNullPointerExceptionでクラッシュします。そう:

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

そのユースケースを解決する方法があるかどうかはわかりません。

編集:ホットキーの回答には、残りの回答が含まれています。

7
zsmb13

Kotlinでは、以下を宣言できます。

  • プリミティブ int as:Int
  • 箱入り int as: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?)
}
1
Avijit Karmakar

Javaで簡単なデモを作成します。

intelliJのKotlinプラグインを使用してKotlinに変換しますIDEAまたはAndroid Studio。

0
dong sheng