[英]How do I get the value of a property with reflection
我想使用帶有注釋的所有屬性的值。 在大多數情況下,我的代碼都能正常工作,我會獲取所有屬性,而僅接受那些具有該批注的屬性。
private inline fun <reified A : Annotation> (target: Any) {
target::class.memberProperties
.filter { it.annotations.any { annotation -> annotation is A } }
.forEach {
// How do I get the value here?
}
}
我想使用它it.get(...)
但get
期望Nothing
作為參數。 getter
。 調用it.call(target)
確實可以,但是它看起來不對,因為有一個我不知道如何調用的實際get
。
那么獲得屬性值的正確方法是什么?
問題歸結為以下事實: T::class
給您KClass<T>
,而t::class
給您KClass<out T>
。 考慮以下:
class Foo {
val foo = 2
val bar = 3
}
fun f() {
val any: Any = Foo()
any::class.memberProperties.forEach {
println(it.get(2)) // Oops
}
}
這將從根本上試圖訪問2.foo
和2.bar
,但它是不允許的,因為get
謹慎的一側允許犯錯類型的參數,而不是Any
。 看來,執行t.javaClass.kotlin
會產生KClass<T>
。 如上所述,濫用它會導致IllegalArgumentException
。
您可以通過提供編譯時保證,確保KClass
適用於該類型, KClass
提供其他任何幫助,從而為編譯器提供更多幫助:
private inline fun <reified A : Annotation, reified T : Any> foo(target: T) {
T::class.memberProperties
.filter { it.annotations.any { annotation -> annotation is A } }
.forEach {
println(it.get(target))
}
}
不幸的是,我不知道在從target
推導出T
是否可以指定A
我還沒有找到像foo<Attr, Bar>(bar)
。
另外,您可以遍歷javaClass
,盡管我認為它的可移植性較差:
private inline fun <reified A : Annotation> foo(target: Any) {
target.javaClass.kotlin.memberProperties
.filter { it.annotations.any { annotation -> annotation is A } }
.forEach {
println(it.get(target))
}
}
我們知道這不會遇到上述問題,因為在兩種情況下我們都傳遞相同的對象。 從調用者的角度來看,這看起來也更好,假設有一個,這可能值得移植。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.