gpt4 book ai didi

reflection - 如何通过反射获取属性的值

转载 作者:行者123 更新时间:2023-12-03 23:52:14 26 4
gpt4 key购买 nike

我想使用所有带有注释的属性的值。在大多数情况下,我的代码有效,我获得了所有属性,并且只使用了那些具有该注释的属性。

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.foo2.bar ,但这是不允许的,因为 get谨慎起见,而不是允许类型为 Any 的参数出错.它似乎在做 t.javaClass.kotlin将产生 KClass<T> , 然而。如上所述滥用它会导致 IllegalArgumentException .

您可以通过提供编译时保证 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))
}
}

不幸的是,我不知道是否可以指定 A同时演绎 T来自 target .我还没有找到像 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))
}
}

我们知道这不会遇到上述问题,因为我们在两种情况下都传递了相同的对象。这在调用者方面看起来也更好,假设有便携性,这可能值得。

关于reflection - 如何通过反射获取属性的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46182841/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com