我有一个对象的实例,我对其进行扫描以查找在其上附加了适当注释的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
}
答案 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")
}