reified
キーワードの目的を理解しようとしています。どうやら、ジェネリックスについての考察を可能にしているようです。
ただし、省略した場合も同様に機能します。これが実際の違いを生むときは誰でも説明してくれますか
reified
キーワードの目的を理解しようとしています。どうやら、ジェネリックスについての考察を可能にしているようです。
ただし、省略した場合も同様に機能します。これが実際の違いを生むときは誰でも説明してくれますか
回答:
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
ます。このような関数により、コンパイラーは、関数が使用されている(関数が「インライン化されている」)すべての場所に関数のバイトコードをコピーします。具象化された型を使用してインライン関数を呼び出すと、コンパイラーは型引数として使用される実際の型を認識し、対応するクラスを直接使用するように生成されたバイトコードを変更します。以下のようなので呼び出すmyVar is T
になるmyVar is String
(type引数があった場合String
、バイトコードで、実行時に)。
どれほど役立つかを示す例を見てみましょうreified
。JSON文字列を、関数のジェネリック型で指定された型を持つプレーンなKotlinオブジェクトに変換しようとする、String
呼び出されたの拡張関数を作成します。これに使用でき、最初のアプローチは次のとおりです。toKotlinObject
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
of 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>()
reified
タイプを含むインライン関数は、Javaコードから呼び出すことができません。
シンプル
* reifiedは、コンパイル時に使用する許可を与えることです(de関数内のTにアクセスするため)
例えば:
inline fun <reified T:Any> String.convertToObject(): T{
val gson = Gson()
return gson.fromJson(this,T::class.java)
}
のような使用:
val jsonStringResponse = "{"name":"bruno" , "age":"14" , "world":"mars"}"
val userObject = jsonStringResponse.convertToObject<User>()
println(user.name)