KotlinにおけるSAMタイプの話
手元にある Java のフレームワークをせっせと Kotlin に置き換えているのだけども、やはり釈然としないことは色々と出てくる。
本日の話は、Java と Kotlin の間で確保されているというInteroperabilityについて。
尚、記事中で使っている Kotlin のコンパイラは 1.0.0。 これらの問題は将来的には改善されるかもしれない。
interface 定義
こういう Java の interface を定義する。
package aaa;
public interface JavaSAM {
String doIt(int i, String s);
static void call(JavaSAM ms) {
System.out.println(ms.doIt(1, "zzzz"));
}
}
Kotlin から Java のメソッドを呼ぶ
これについては、マニュアル通りなので特に変な部分は無いように思う。
fun java_interop() {
// IntelliJ says me `Convert to Lambda`
JavaSAM.call(object : JavaSAM {
override fun doIt(i: Int, s: String?): String? {
return "zzz$i$s"
}
})
JavaSAM.call { i: Int, s: String? -> "zzz$i$s" }
JavaSAM.call { i, s -> "zzz$i$s" }
}
最初の呼び出しは、object 記法で JavaSAM を実装するオブジェクトをアドホックに作ってJavaSAM#callに渡すやり方。
冗長で誰も得しない感じなので IntelliJ はラムダ式にしろって煽ってくる。
二番目は、引数の型を明示しつつラムダ式にしてみた。
三番目は、省略できるものを全部省略した形。
既存の Java API が SAM タイプを要求してくる場合、Kotlin のラムダ式をアドホックに渡してあげれば、足りない部分は Kotlin が適宜補ってくれるという素晴らしい形。
Java6 相当の環境である Android アプリを作るなら喉から手が出る程欲しい記法だろう。
