1. ホーム

[解決済み】JavaからKotlinの拡張関数にアクセスする

2022-04-12 17:12:56

質問

Javaコードから拡張機能にアクセスすることは可能ですか?

Kotlinファイルで拡張関数を定義しました。

package com.test.extensions

import com.test.model.MyModel

/**
 *
 */
public fun MyModel.bar(): Int {
    return this.name.length()
}

ここで MyModel は(生成された)Javaクラスです。 さて、私は通常のJavaコードでこれにアクセスしたいと思いました。

MyModel model = new MyModel();
model.bar();

しかし、それではうまくいきません。 IDEが認識しないのは bar() メソッドにアクセスできず、コンパイルに失敗します。

うまくいくのは、kotlinのスタティック関数を使ったものです。

public fun bar(): Int {
   return 2*2
}

を使用することで import com.test.extensions.ExtensionsPackage ということで、私のIDEは正しく設定されているようです。

kotlinのドキュメントからJava-interopのファイルを全部探したり、ググってみたりしたのですが、見つかりませんでした。

私は何を間違えているのでしょうか?こんなこと可能なのでしょうか?

解決方法は?

あるファイルで宣言されたすべてのKotlin関数は、デフォルトで同じパッケージ内のクラスのスタティックメソッドにコンパイルされ、Kotlinソースファイルから派生した名前(最初の文字が大文字で、かつ ".kt" 拡張子を "Kt" というサフィックスがつきます)。拡張関数用に生成されたメソッドには、拡張関数のレシーバタイプを指定した第1パラメータが追加されます。

これを元の問題に当てはめると、JavaコンパイラーはKotlinのソースファイルを、名前 例.kt

package com.test.extensions

public fun MyModel.bar(): Int { /* actual code */ }

を、あたかも次のようなJavaクラスが宣言されているかのように表現します。

package com.test.extensions

class ExampleKt {
    public static int bar(MyModel receiver) { /* actual code */ }
}

Java の観点からは拡張クラスでは何も起こらないので、このようなメソッドにアクセスするためにドットシンタックスを使うことはできません。しかし、それらは通常のJavaの静的メソッドとして呼び出すことは可能です。

import com.test.extensions.ExampleKt;

MyModel model = new MyModel();
ExampleKt.bar(model);

ExampleKtクラスは静的インポートを使用することができます。

import static com.test.extensions.ExampleKt.*;

MyModel model = new MyModel();
bar(model);