私はリフレクションで遊んでいます。この問題が出てきました。 ::class
構文を介して結合クラス参照を使用している場合、私は共変KClassの種類を取得:バインドされたクラス参照が共変型を返すようにする目的は何ですか?
fun <T> foo(entry: T) {
with(entry::class) {
this // is instance of KClass<out T>
}
}
私は、ドキュメントから学ぶことができるように、これはオブジェクトの正確な型を返します、ケースには、サブタイプのインスタンスでありますT
であり、したがって分散変更子である。これは(私が何をしようとしているとする)T
クラスで宣言されたプロパティを取得し、その値を取得防止
fun <T> foo(entry: T) {
with(entry::class) {
for (prop in memberProperties) {
val v = prop.get(entry) //compile error: I can't consume T
}
}
}
は、しかし、私は解決策を取得するには、オブジェクト参照にjavaClass.kotlin
拡張機能を使用していることがわかりました代わりに、不変型:
fun <T> foo(entry: T) {
with(entry.javaClass.kotlin) {
this // is instance of KClass<T>
}
}
このようにして、実行時に正確な型と型を消費する可能性の両方が得られます。私はそれが正しい得た場合::class
があり、
class Derived: Base()
fun foo(entry: Base) {
with(entry.javaClass.kotlin) {
println(this == Derived::class)
}
}
fun main(args: Array<String>) {
val derived = Derived()
foo(derived) // prints 'true'
}
:私は後者の方法で、一般的なのではなく、スーパータイプを使用する場合
興味深いことに、私はまだ分散を必要とせずに、正しい型へのアクセスを取得しますワイルドカードを含むバリアント型を返すjava getClass
を呼び出し、javaClass
はgetClass
で、特定の型へのキャストを呼び出します。 しかし、実行時に厳密なクラスにアクセスして自由に使用できる他の方法があるとすれば、型を生成することだけを制限するときに共存するKClassが必要なのはなぜですか?より即座に::class
は、設計上不変型を返すべきです。
私はあなたの言うことを理解しています。しかし、私のポイントは、もし私がsomeBase()。javaClassを使うならば。kotlin、私はまだ実行時に正しいサブタイプ(派生)を持っていますが、それらの拡張関数はジェネリックを使用するので、コンパイル時にも分散はありません。 :: class構文は、javaClass.kotlinのように機能するように改良されています。javaClass.kotlinは、イディオム的にはあまり即座ではありません。彼らは同じことをして、kotlinクラスを返すように思えますが、後者はもっと冗長でありながらより良い仕事をしてくれます。 – devrocca
これは逆です: '.javaClass'は以前に導入されました。誤った設計とみなされた。 '.javaClass'は廃止されました([1.1 RCで)](https://blog.jetbrains.com/kotlin/2017/02/kotlin-1-1-release-candidate-is-here/) 1.1最終リリースでは、廃止予定が削除されました。 – hotkey
面白いことです。しかし、リフレクションによって取得されたプロパティを呼び出す必要がある場合は、受信者が必要です。共変タイプではバインドされたプロパティを使用できません。 '.javaClass'は利用できませんでした。 – devrocca