1

我有一个对象的实例,我会扫描它以查找附加了正确注释的 memberProperties。然后,我想根据它们的返回类型进行过滤。例如,如果声明如下:class AutoValidatedThing : AutoValidatedUserInputComponent {...}并且目标实例包含 a @ValidComponent val someProperty: AutoValidatedThing = ...,我希望将somePropertyas aAutoValidatedUserInputComponent放在以下代码块的末尾:

    val invalidOnes = this::class.memberProperties
        .filter { it.javaField != null && it.javaField!!.isAnnotationPresent(ValidComponent::class.java) }
        .filter { val annotations = it.javaField?.annotations; annotations != null
                && annotations.map { ann -> ann.annotationClass }.contains(ValidComponent::class)
                && it.returnType is AutoValidatedUserInputComponent }
        .map { it.getter.call() as AutoValidatedUserInputComponent }

it.returnType is AutoValidatedUserInputComponent总是返回 false。

AutoValidatedUserInputComponent是一个简单的界面:

interface AutoValidatedUserInputComponent {
    fun blabla() : SomeType
}
4

1 回答 1

2

调用returnTypeaKProperty不会返回具有给定类型的实例,您可以对其进行is检查 - 它返回一个描述该类型的反射类,具体来说KType,它当然不会实现您的接口。代替 using is,您可以调用isSubTypeOf它,并检查它是否是另一个给定的子类型KType

对于该调用,您需要KType为自己的接口获取一个 - 为此,您可以createType在其上使用KClass

val targetType = AutoValidatedUserInputComponent::class.createType(nullable = true)

createType可空性部分由您决定,例如,如果您的接口碰巧有类型参数,还有其他可选参数。

然后,正如我提到的,您可以使用isSubTypeOf

val invalidOnes = this::class.memberProperties
        .filter { it.javaField != null && it.javaField!!.isAnnotationPresent(ValidComponent::class.java) }
        .filter {
            val annotations = it.javaField?.annotations
            annotations != null
                    && annotations.map { ann -> ann.annotationClass }.contains(ValidComponent::class)
                    && it.returnType.isSubtypeOf(targetType)
        }
        .forEach {
            println("Found field with annotation and given supertype: $it")
        }
于 2018-07-01T11:22:43.630 回答