[解決済み] Kotlinでジェネリックパラメータクラスを取得する方法
質問
Firebaseの
snapshot.getValue()
は以下のように呼ばれることを期待します。
snapshot?.getValue(Person::class.java)
しかし、私は
Person
をクラス宣言で渡される一般的なパラメータで置き換えたいと思います。
class DataQuery<T : IModel>
で、そのジェネリックパラメータを使って、以下のようなことをします。
snapshot?.getValue(T::class.java)
というエラーが表示されます。
はクラスリテラルの左側で使用することができます。
C#のようにジェネリックパラメータにクラス制約を与えることは可能ですか?またはジェネリックパラメータの型情報を取得するために使用できる他の構文がありますか?
どのように解決するのですか?
ジェネリックパラメータTを持つクラスでは、JVMが型情報を消去するため、Tの型情報がないため、これを行うことはできません。 したがって、このようなコードは動作しません。
class Storage<T: Any> {
val snapshot: Snapshot? = ...
fun retrieveSomething(): T? {
return snapshot?.getValue(T::class.java) // ERROR "only classes can be used..."
}
}
しかし、Tの型を再定義し、インライン関数内で使用すれば、これを動作させることができます。
class Storage {
val snapshot: Snapshot? = ...
inline fun <reified T: Any> retrieveSomething(): T? {
return snapshot?.getValue(T::class.java)
}
}
インライン関数が public の場合、クラスの public メンバにのみアクセスできることに注意してください。 1つはインラインではないクラスパラメータを受け取り、プライベートな内部にアクセスするもので、もう1つは推論された型パラメータから再定義を行うインラインヘルパー関数です。
class Storage {
private val snapshot: Snapshot? = ...
fun <T: Any> retrieveSomething(ofClass: Class<T>): T? {
return snapshot?.getValue(ofClass)
}
inline fun <reified T: Any> retrieveSomething(): T? {
return retrieveSomething(T::class.java)
}
}
また
KClass
の代わりに
Class
を使うことで、Kotlin のみの呼び出し元は単に
MyClass::class
の代わりに
MyClass::class.java
クラスがジェネリックのインラインメソッドと協調するようにしたい場合(つまり、クラスが
Storage
型のオブジェクトのみを格納する
T
):
class Storage <T: Any> {
val snapshot: Snapshot? = ...
inline fun <reified R: T> retrieveSomething(): R? {
return snapshot?.getValue(R::class.java)
}
}
インライン関数で再定義された型へのリンクです。 https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters
関連
-
[解決済み] リフレクションを使ってジェネリックメソッドを呼び出すにはどうしたらいいですか?
-
[解決済み] Javaで汎用配列を作成する方法は?
-
[解決済み] 汎用型Tのクラスインスタンスを取得する方法を教えてください。
-
[解決済み] 汎用クラスやメソッドのメンバからTの型を取得する方法
-
[解決済み] Kotlin 三項条件演算子
-
[解決済み】TをEnumに拘束するGenericメソッドの作成
-
[解決済み】Nullable型をジェネリックパラメータにすることは可能か?
-
[解決済み】Scala。抽象型とジェネリックス
-
[解決済み] 汎用型パラメータで静的メソッドを呼び出す
-
[解決済み] Kotlinの汎用拡張クラスとインターフェイスの実装
最新
-
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のreifiedキーワードはどのように機能するのですか?
-
[解決済み】Scala。抽象型とジェネリックス
-
[解決済み] Kotlinのジェネリックにおける "*"と "Any "の違いについて
-
[解決済み] なぜ例がコンパイルできないのか、別名、(co-, contra-, in-)分散はどのように機能するのか?
-
[解決済み] KotlinでGsonを使ったTypeToken + ジェネリックの使い方
-
[解決済み] kotlinのoutキーワードとは
-
[解決済み] なぜGoにはジェネリックがないのか?
-
[解決済み] Kotlinの汎用拡張クラスとインターフェイスの実装
-
[解決済み] MIN および MAX マクロの Swift 対応版