Android開発において次の場面に遭遇
- メソッドに *.class = クラスを引数で渡したい
- 例えば別Activityを起動する時とか、
- kotlinだとどうやればクラスを渡せるの?
Javaに慣れているとkotlinで少し悩みます。
それには少し表現を変えるだけなので、
Kotlinでclassを引数で渡す方法をまとめました。
このページの目次
Javaではクラスリテラル *.class で引数渡しできた
Kotlinではなく、旧来のJavaの場合。
Activityクラスなどを次の形式で表しました。
▼ こういう表現(クラスリテラル)
1 2 |
/// クラスリテラル MainActivity.class |
上記の *.class のような表現はクラスリテラルと呼ばれます。実際はClassオブジェクトであり、 MainActivity.class.getName() などのメタ情報の取得にも使えます。
Android開発でもよく見かける書き方です。
そもそもクラスリテラルとは何か(脱線)
クラスリテラルは聞きなれない言葉です。
そこでググると分かりやすい解説を見つけました。
▼ クラスリテラルって何だ?…に対する答え
Class
クラスは、クラスを表すクラスです。リフレクションの中心的存在です。Class
クラスの定義はClass<T>
のようにジェネリクス付きになっています。T
には表しているクラスが指定されます。全てのクラスには、
class
というstaticフィールドのようなもの(後述)が暗黙的に作成されています。このフィールドのようなものには、そのクラスを表すClass
インスタンスが代入されています。
.class
は正確には「クラスリテラル」と呼ばれるリテラルで、フィールドではありません(参考URL)。ただし、前述の説明ではイメージ重視で「フィールドのようなもの」として説明しています。これに加えて、全てのクラスには
getClass()
メソッドが定義されています(java.lang.Object
クラスで定義されています)。このメソッドの戻り値は、.class
と同じ「そのクラスを表すClass
インスタンス」です。引用元 : 入門Javaリフレクション
元々リフレクションの機能としてメタ的なClassクラスが用意されていて、 .class あるいは .getClass() はそれにアクセスする手段とのことです。
そして .class の方を「クラスリテラル」と呼んでいる……
言葉の定義はそんな感じみたいですね。
Androidでクラスリテラルを使う代表例
もっとも目にするのは別Activityに遷移するコードとかです。
▼ 例えば別Activityを開きたい場合など
1 2 |
Intent intent = new Intent(this, NextActivity.class); startActivity(intent); |
こういうとこでクラスリテラルって使われてます。
同じことをKotlinでしたかったです。
KotlinではJava的なクラスリテラルは使えない
ここからはKotlinでの話。
残念ながらJava的クラスリテラルは使えません。
▼ このような書き方は不正。ダメ
1 2 |
/// クラスリテラル MainActivity.class |
このような記述はKotlinには存在しないからエラーになります。KotlinではJava的クラスリテラルの代用があるかどうかも分からないです。
少なくともKotlin自体にはクラスリテラルは存在しないみたいです。というか Kotlin ⇒ Java ⇒ クラスリテラル のように経由して呼び出せるみたい(後述)
Kotlinでクラスを引数に渡すなら ::class を使う
それではclassを引数に渡す正しい方法について
結論から書くと ::class.java を使えばいいです。
▼ つまりは次のような書き方
1 2 |
/// Classオブジェクト取得 MainActivity::class.java |
初めて見ると「なんだこれ?」となる書き方ですが、この記述はJavaにおける MainActivity.class と同じく使えます( = Classオブジェクト)
Kotlinではこのようにしか書けません。
Kotlinで別ActivityをIntentから開く書き方例
最後に具体的かつ実用的な例を1つだけ紹介
Intentから別Activityなどを開く場合です。
▼ Kotlinではこのように書くのが正解
1 2 3 4 5 6 |
/// 別Activityを開く val intent = Intent(this, /// ▼ Classオブジェクトを渡す NextActivity::class.java ) startActivity(intent) |
こうするのがKotlinにおける正しい方法です。
知らないと少し困るかもしれません。
以上、Kotlinで引数にclassを渡す方法でした。ではまた