我有一个简单的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
...所以它会再次丢失注释。
答案 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
,其中 包含注释。