memberProperty returnType超类的类型检查失败

时间:2018-07-01 11:10:12

标签: reflection kotlin kotlin-reflect

我有一个对象的实例,我对其进行扫描以查找在其上附加了适当注释的memberProperty。然后,我想根据它们的返回类型进行过滤。 例如,如果声明如下:class AutoValidatedThing : AutoValidatedUserInputComponent {...}并且目标实例包含一个@ValidComponent val someProperty: AutoValidatedThing = ...,那么我想将someProperty作为AutoValidatedUserInputComponent的形式带到以下内容的末尾代码块:

    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
}

1 个答案:

答案 0 :(得分:1)

KProperty上调用returnType不会返回具有给定类型的实例,您可以对它进行is检查-它会返回一个描述该类型的反射类,特别是{ {3}},这当然不会实现您的界面。除了使用is之外,您还可以调用KType,并检查它是否是给定KType的另一个子类型。

对于该呼叫,您需要为自己的界面获取一个KType-为此,您可以在其KClass上使用isSubTypeOf

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")
        }