从KType中检索注释

时间:2018-02-23 12:49:15

标签: java reflection annotations jvm kotlin

我有一个简单的TYPE_USE注释:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
public @interface Cool {
}

以下示例Kotlin类:

class Item(
        id: Long? = null,
        var names: List<@Cool String> = emptyList())

有没有办法使用Java反射提取注释?

Item.class.getMethod("getName").getAnnotatedReturnType()会丢失注释,与获取字段相同。

我甚至可以从Kotlin获得注释吗?

Item::class.memberProperties.elementAt(0).returnType返回带有注释的KType,但我看不到提取它的方法。即使我有JDK8扩展名,也不能从AnnotatedType获得KType

我看到的只是KType#javaType,但这会返回Type,而不是AnnotatedType ...所以它会再次丢失注释。

1 个答案:

答案 0 :(得分:3)

修改:this is a bug and has been reported 。还没有目标版本,但其优先级已设置为Major。这已在Kotlin 1.3中修复。

<击> TL; DR:不......?

使用Set注释的项是第一个类型参数,因此您需要检索它:

@Cool

不幸的是,似乎没有办法在val type = Item::class.memberProperties.elementAt(0).returnType val arg = type.arguments[0] println(arg) // KTypeProjection(variance=INVARIANT, type=@Cool kotlin.String) 上检索注释(正如您所提到的那样)。

奇怪的是,这是一个非常内部的过程。查看KTypeImpl的来源显示KType是通过toString实现的,(其中类型为ReflectionObjectRenderer.renderType(type))已委托给KotlinType,我们可以见a DescriptorRenderer with modifiers ALL

渲染器检查类型是否为DescriptorRenderer.FQ_NAMES_IN_TYPES的子类,然后访问其kotlin.reflect.jvm.internal.impl.descriptors.annotations.Annotated属性。

我试过了:

annotations

不幸的是,我为val retType = Item::class.memberProperties.elementAt(0).returnType val arg = retType.arguments[0] println(arg) // KTypeProjection(variance=INVARIANT, type=@Cool kotlin.String) val type = arg.type!! println(type) val field = type::class.memberProperties.first { it.name == "type" } val kotlinType = field.call(type) as Annotated println(kotlinType) println(kotlinType.annotations) 获得ClassNotFoundException,因此 选项已消失。

同样奇怪的是,org.jetbrains.kotlin.types.KotlinType不是KType的子类型(这就是为什么它没有KAnnotatedElement属性)。

我认为这可能是疏忽,因为annotations包裹了KTypeImpl,其中 包含注释。