从KType检索注释 [英] Retrieve annotations from 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.
推荐答案
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).
奇怪的是,这是一个非常内部的过程.寻找 KTypeImpl
表明toString
是通过ReflectionObjectRenderer.renderType(type)
(类型为KotlinType
)实现的,委托给DescriptorRenderer.FQ_NAMES_IN_TYPES
,我们可以看到它是
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.KotlinType
的ClassNotFoundException
,所以那个选项不见了.
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屋!