从 KType 检索注释 [英] Retrieve annotations from KType

查看:19
本文介绍了从 KType 检索注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的 TYPE_USE 注释:

@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})公共@interface 酷{}

以及以下示例 Kotlin 类:

class Item(id:长?= 空,变量名称:列表<@Cool String>= 空列表())

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

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

我什至可以从 Kotlin 获取注释吗?

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

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

解决方案

这是一个错误,已被报告.目前还没有目标版本,但其优先级已设置为 Major. 这已在 Kotlin 1.3 中修复.

<小时>

<罢工>TL;DR:没有...?

<小时>

@Cool 注释的项目是第一个类型参数,因此您需要检索它:

val type = Item::class.memberProperties.elementAt(0).returnTypeval arg = type.arguments[0]println(arg)//KTypeProjection(variance=INVARIANT, type=@Cool kotlin.String)

不幸的是,似乎没有办法检索 KType 上的注释(正如您所提到的).

奇怪的是,这是一个非常内部的过程.查看 KTypeImpl 显示 toString 是通过 ReflectionObjectRenderer.renderType(type) 实现的,(其中 type 是一个 KotlinType) 委托给 DescriptorRenderer.FQ_NAMES_IN_TYPES,我们可以看到它是 一个带有修饰符ALLDescriptorRenderer.

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

我试过了:

val retType = Item::class.memberProperties.elementAt(0).returnTypeval arg = retType.arguments[0]println(arg)//KTypeProjection(variance=INVARIANT, type=@Cool kotlin.String)val 类型 = arg.type!!打印(类型)val field = type::class.memberProperties.first { it.name == "type" }val kotlinType = field.call(type) as Annotated打印(科特林类型)println(kotlinType.annotations)

不幸的是,我收到了 org.jetbrains.kotlin.types.KotlinTypeClassNotFoundException,所以 那个 选项消失了.

同样奇怪的是,KType 不是 KAnnotatedElement 的子类型(这就是它没有 annotations 属性的原因).

我想这可能是一个疏忽,因为 KTypeImpl 包装了一个 KotlinType,它确实包含注释.

I have a simple TYPE_USE annotation:

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

And the following sample Kotlin class:

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

Is there any way to extract the annotation using Java reflection?

Item.class.getMethod("getName").getAnnotatedReturnType() loses the annotations, same with getting the field.

Can I even get the annotation from Kotlin?

Item::class.memberProperties.elementAt(0).returnType return a KType which has the annotation, but I don't see a way to extract it. Nor to obtain an AnnotatedType from KType, even though I have JDK8 extensions.

All I see is KType#javaType but this returns Type, not AnnotatedType... so it looses the annotations again.

解决方案

Edit: this is a bug and has been reported. There is not yet a target version, but its priority has been set to Major. This was fixed in Kotlin 1.3.


TL; DR: no...?


The item annotated with @Cool is the first type argument, so you need to retrieve it:

val type = Item::class.memberProperties.elementAt(0).returnType

val arg = type.arguments[0]
println(arg) // KTypeProjection(variance=INVARIANT, type=@Cool kotlin.String)

Unfortunately there doesn't seem to be a way to retrieve the annotations on a KType (as you have mentioned).

Strangely, this is a very internal process. Looking into the source for KTypeImpl shows that toString is implemented via ReflectionObjectRenderer.renderType(type), (where type is a KotlinType) which is delegated to DescriptorRenderer.FQ_NAMES_IN_TYPES, which we can see is a DescriptorRenderer with modifiers ALL.

The renderer checks if the type is a subclass of kotlin.reflect.jvm.internal.impl.descriptors.annotations.Annotated, and then accesses its annotations property.

I tried this:

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)

Unfortunately, I get a ClassNotFoundException for org.jetbrains.kotlin.types.KotlinType, so that option is gone.

Equally strangely, KType is not a subtype of KAnnotatedElement (which is why it has no annotations property).

I suppose this may have been an oversight, since KTypeImpl wraps a KotlinType, which does contain annotations.

这篇关于从 KType 检索注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆