【问题标题】:Kotlin - return all properties that implement an interface and are annotatedKotlin - 返回所有实现接口并被注释的属性
【发布时间】:2023-02-21 01:39:09
【问题描述】:
我有一个简单的 kotlin 1.7.10 程序 - 我有一个名为 Rule 的接口和名为 NextRule 的属性注释 + 2 个实现
import kotlin.reflect.KClass
interface Rule {
fun process(s: String): String
}
@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.SOURCE)
@MustBeDocumented
annotation class NextRule
class EndRule() : Rule {
override fun process(s: String) = "$s END"
}
class StartRule(
@NextRule
private val endRule: EndRule
) : Rule {
override fun process(s: String): String = "$s START"
}
我想创建一个函数,该函数将采用实现Rule接口的对象并为每个字段返回,该对象也实现Rule并用NextRule注释其KClass - 基本上是一个类似于Rule -> Seq<KClass<out Rule>>的函数 - 一些东西喜欢
fun getAllNextRuleAnnotatedClasses(rule: Rule): List<KClass<out Rule>> {
for(property in rule::class.properties){
if(property.returnType.class implements Rule && property isAnnotatedWith NextRule){
yield property::class
}
}
}
如何实现?
【问题讨论】:
标签:
kotlin
kotlin-reflect
【解决方案1】:
你可以试试这个:
fun getAllNextRuleAnnotatedClasses(rule: Rule): List<KClass<out Rule>> {
return rule::class.memberProperties
.filter { it.returnType.classifier == Rule::class }
.filter { it.findAnnotation<NextRule>() != null }
.map { it.returnType.classifier as KClass<out Rule> }
}
【解决方案2】:
我设法解决了
@Target(AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.TYPE_PARAMETER)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class NextRule
fun getAllNextRuleAnnotatedClasses(rule: Rule): List<Rule> {
return sequence {
rule::class.primaryConstructor!!.parameters.forEach { param ->
if (param.type.jvmErasure.isSubclassOf(Rule::class) && param.findAnnotation<NextRule>() != null) {
val field = rule::class.java.getDeclaredField(param.name!!)
val isAccessible = field.canAccess(rule)
if (!isAccessible) {
field.setAccessible(true);
}
val value = field.get(rule) as Rule
if (!isAccessible) {
field.setAccessible(false);
}
yield(value)
}
}
}.toList()
}