Reified Types in Kotlin翻訳
以下の記事の翻訳になります。
Reified Types in Kotlin
ジェネリックスを使用しているときにJava開発者を最も苛立たせる制限の1つは、型を直接使用できないということです。
通常、これはClassインスタンスを関数のパラメータとして渡すことで解決されますが、コードはより複雑になり魅力的ではありません。
Kotlinでは既に議論したインライン関数のおかげで、関数内で型が使用可能になる具象化型パラメーターを使えます。
これはなんのためにあるのでしょうか?きっとあなたも気に入ることでしょう。
具象化された型
先に言及したように、ある型をreified修飾子でマーキングすることで、関数内でその型を使用することができます。
そのためにはinline修飾子を使用した関数であることが重要です。なぜならその型にアクセスするために、実行箇所でコードを置き換える必要があるためです。
関数で型を使用できないという事実は、Java仮想マシンの限界であり、それはその制限をスキップする “トリック"です。
Activityへのナビゲート
これはAndroidに適用される最も典型的なケースです。
Javaでは、startActivityを呼出時に遷移先クラスをパラメータとして指定する必要があります。
Kotlinでは、関数に型を追加することでシンプルにできます。
inline fun <reified T : Activity> Activity.startActivity() { startActivity(Intent(this, T::class.java)) }
Activityの遷移はこんなに簡単になりました
startActivity<DetailActivity>()
キャスト付きのFindView
多くのAndroid開発者が使用していない、かつ非常に有用なJavaのテクニックは、ジェネリックスを使用して、結果が割り当てられた変数の型にキャストされたオブジェクトを返すことです。
Javaでは、このような関数を作成することができます。
public <T extends View> T findView(Activity activity, int id) { return (T) activity.findViewById(id); }
そして、その関数を使用してキャストされたオブジェクトを返します。
TextView textView = Utils.findView(activity, R.id.welcomeMessage);
Kotlinでは同様のことが拡張機能のおかげでより簡単にできます。
fun <T : View> Activity.findView(id: Int) = findViewById(id) as T val textView = activity.findView<TextView>(R.id.welcomeMessage)
しかしどちらの場合でも、T型にアクセスできないため、コンパイラはキャストが有効であることを確かめることができないとわかるでしょう。そのため警告が表示されます。
具体化されたタイプでは、この問題を避けることができます。
inline fun <reified T : View> Activity.findView(id: Int) = findViewById(id) as T
結論
具体化された型では、Javaでは不可能なことを行うことができ、他の機能をより安全に行うことさえできます。
こうして、関数にClass型の引数を渡さずに済むようになりました。
加えて拡張関数のおかげで、Androidのようなフレームワークの上に新しい関数を作成することができます。記事中で既にstartActivityメソッドのようなAndroidAPIのいくつかで拡張関数で使用しています。
もしあなたが自分のアプリを開発するためにKotlinを使い始めたいなら、無料ガイドとAndroid開発者向けのKotlin本を見てみることをお勧めします。