[解決済み】Kotlinのreifiedキーワードはどのように機能するのですか?
質問
の目的を理解しようとしています。
reified
というキーワードがあるようですが、どうやら
ジェネリックスに対するリフレクションを可能にします。
.
しかし、それを省くと、同じようにうまく動作するのです。どなたか、どのような場合に実際の 差 ?
解決方法は?
TL;DR: What is
reified
に良い
fun <T> myGenericFun(c: Class<T>)
のような汎用的な関数の本体で
myGenericFun
という型にアクセスすることはできません。
T
なぜなら、それは
コンパイル時のみ利用可能
しかし
消去
を実行時に表示します。したがって、関数本体の中でジェネリックタイプを通常のクラスとして使いたい場合は、次のようにする必要があります。
明示的にパラメータとしてクラスを渡す
で示したように
myGenericFun
.
を作成した場合
inline
関数に
リファイド
T
のタイプは
T
は実行時にもアクセスできるため、実行時に
Class<T>
を追加しました。を使うことができます。
T
を通常のクラスと同じように扱うことができます。
のインスタンスです。
T
であれば、簡単にできます。
myVar is T
.
このような
inline
という関数があります。
reified
タイプ
T
は次のようになります。
inline fun <reified T> myGenericFun()
どのように
reified
作品
のみを使用することができます。
reified
との組み合わせで
inline
関数を使用します。こうすることで、コンパイラは関数のバイトコードをその関数が呼び出されたすべての場所にコピーするように指示します(コンパイラは関数を "inlines"するのです)。を呼び出すと
inline
関数を
reified
型の引数として渡された実際の型をコンパイラが知ることができ、生成されたバイトコードを修正して対応するクラスを直接使用できるようにしなければなりません。したがって、以下のような呼び出しは
myVar is T
は次のようになります。
myVar is String
をバイトコードで指定します(type 引数が
String
).
使用例
では、どのように役立つかを示す例を見てみましょう。
reified
を使用することができます。
の拡張機能を作りたいと思います。
String
という
toKotlinObject
この関数は、JSON 文字列を、この関数の汎用型である
T
. 私たちは
com.fasterxml.jackson.module.kotlin
を使用することができ、最初のアプローチは以下の通りです。
a) 型を再定義しない最初のアプローチ
fun <T> String.toKotlinObject(): T {
val mapper = jacksonObjectMapper()
//does not compile!
return mapper.readValue(this, T::class.java)
}
は
readValue
メソッドは、パースすることになっている型を受け取ります。
JsonObject
に変換します。もし私たちが
Class
型パラメタの
T
の場合、コンパイラは文句を言う。
"再定義された型パラメータとして 'T' を使用することはできません。代わりにクラスを使用してください。
b) 明示的な回避策
Class
パラメータ
fun <T: Any> String.toKotlinObject(c: KClass<T>): T {
val mapper = jacksonObjectMapper()
return mapper.readValue(this, c.java)
}
回避策として
Class
の
T
をメソッドのパラメータにし、それを引数として
readValue
. これは、一般的なJavaコードでよく見られるパターンです。次のように呼び出すことができます。
data class MyJsonType(val name: String)
val json = """{"name":"example"}"""
json.toKotlinObject(MyJsonType::class)
c) Kotlinの方法。
reified
を使用することで
inline
関数と
reified
型パラメータ
T
を使用すると、関数を別の方法で実装することが可能になります。
inline fun <reified T: Any> String.toKotlinObject(): T {
val mapper = jacksonObjectMapper()
return mapper.readValue(this, T::class.java)
}
を取る必要はありません。
Class
の
T
を追加しました。
T
は、普通のクラスのように使うことができます。クライアント側では、このようなコードになります。
json.toKotlinObject<MyJsonType>()
重要なお知らせ:Javaでの作業について
を持つインライン関数は
reified
型は
Javaから呼び出すことができない
のコードに置き換えられます。
関連
-
[解決済み] golangでチャンTの満杯を監視する
-
[解決済み] KotlinのPair用コンパレータ
-
[解決済み] List<T>をオブジェクトのプロパティでソートする方法
-
[解決済み】KotlinでJavaの静的メソッドに相当するものは何ですか?
-
[解決済み】Kotlinのreifiedキーワードはどのように機能するのですか?
-
[解決済み】JavaでClass<T>を使用するには?
-
[解決済み】Scala。抽象型とジェネリックス
-
[解決済み] Kotlinのジェネリックにおける "*"と "Any "の違いについて
-
[解決済み] なぜ例がコンパイルできないのか、別名、(co-, contra-, in-)分散はどのように機能するのか?
-
[解決済み] KotlinでGsonを使ったTypeToken + ジェネリックの使い方
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] golangでチャンTの満杯を監視する
-
[解決済み] KotlinのPair用コンパレータ
-
[解決済み】Kotlinのreifiedキーワードはどのように機能するのですか?
-
[解決済み】Scala。抽象型とジェネリックス
-
[解決済み] Kotlinのジェネリックにおける "*"と "Any "の違いについて
-
[解決済み] なぜ例がコンパイルできないのか、別名、(co-, contra-, in-)分散はどのように機能するのか?
-
[解決済み] KotlinでGsonを使ったTypeToken + ジェネリックの使い方
-
[解決済み] kotlinのoutキーワードとは
-
[解決済み] なぜGoにはジェネリックがないのか?