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

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

问题描述

我有一个简单的TYPE_USE批注:

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

以及以下示例Kotlin类:

And the following sample Kotlin class:

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

有什么方法可以使用Java反射来提取注释?

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

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

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

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

Can I even get the annotation from Kotlin?

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

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.

我看到的只是KType#javaType,但这将返回Type,而不是AnnotatedType ...,因此会再次松开注释.

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

推荐答案

此问题已在Kotlin 1.3中修复.

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:不...?

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

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)

不幸的是,似乎没有一种方法可以检索KType上的注释(如前所述).

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.

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

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

我尝试过:

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)

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

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

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

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

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

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

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

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