英文:
How do I access type use annotations in kotlin through reflection?
问题
一个我正在使用的库利用类型使用注解来对变量添加约束。例如,如果您想要一个可配置的不透明度(以百分比表示,由float
类型表示),您可以对float
类型进行注解:
public @Setting.Constrain.Range(min = 0, max = 1, step = 0.1) float opacity = 1f;
我无法让同样的库在相同的 Kotlin 代码上工作。
为了简化问题,让我们自己声明注解和使用方式:
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
public @interface JavaAnnot { }
public class TestJava {
@JavaAnnot int a = 5;
public static void main(String[] args) {
System.out.println(TestJava.class.getDeclaredFields()[0].getAnnotatedType().isAnnotationPresent(JavaAnnot.class));
}
}
运行 TestJava#main
会得到 true
,表明类型上存在 JavaAnnot
注解。
如果我们引入一个新的 Kotlin 类 TestKotlin
,其中有一个类似的 a
字段和带有注解的类型:
class TestKotlin {
val a: @JavaAnnot Int = 5
}
之前的检查,现在针对 TestKotlin
类:
TestKotlin.class.getDeclaredField("a").getAnnotatedType().isAnnotationPresent(JavaAnnot.class)
得到 false
,表明 JavaAnnot
注解在 a
的 Int
类型上不存在,尽管我们明确对其进行了注解。
我尝试过:
- 使用
@JvmField
对a
进行注解。但这并没有改变行为。 - 在 Kotlin 中声明一个相同的注解:
@Target(AnnotationTarget.TYPE)
@Retention(AnnotationRetention.RUNTIME)
annotation class KotlinAnnot
val a: @KotlinAnnot Int = 5
但这没有解决问题。
- 检查通过反射可访问的其他元数据:我没有找到有用的信息。
这是 Kotlin 的一个 bug 吗?类型使用注解在 Kotlin 中不存在,还是语法不同?我做错了什么?
谢谢。
英文:
A library I'm using utilises type use annotations to add constraints to variables. For example, if you wanted a configurable opacity (in percent, represented by a float
), you'd annotate the float
type:
public @Setting.Constrain.Range(min = 0, max = 1, step = 0.1) float opacity = 1f;
I could not get the same library to work on identical kotlin code.
To simplify the question, let's declare the annotation and usage ourselves:
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
public @interface JavaAnnot { }
public class TestJava {
@JavaAnnot int a = 5;
public static void main(String[] args) {
System.out.println(TestJava.class.getDeclaredFields()[0].getAnnotatedType().isAnnotationPresent(JavaAnnot.class));
}
}
Running TestJava#main
yields true
, indicating that the JavaAnnot
annotation is present on the type.
If we introduce a new kotlin class TestKotlin
with a similar a
field and annotated type:
class TestKotlin {
val a: @JavaAnnot Int = 5
}
The previous check, now on the TestKotlin
class:
TestKotlin.class.getDeclaredField("a").getAnnotatedType().isAnnotationPresent(JavaAnnot.class)
yields false
, indicating that the JavaAnnot
annotation is NOT present on the Int
type of a
, even though we clearly did annotate it.
I've tried:
- Annotating
a
with@JvmField
. This did not change the behaviour. - Declaring an identical annotation in kotlin:
@Target(AnnotationTarget.TYPE)
@Retention(AnnotationRetention.RUNTIME)
annotation class KotlinAnnot
val a: @KotlinAnnot Int = 5
Did not fix the problem.
- Inspecting other metadata accessible through reflection: I did not find anything useful.
Is this a kotlin bug? Do type use annotations not exist in kotlin, or is the syntax different? What am I doing wrong?
Thanks.
答案1
得分: 1
自 Kotlin 字段的 AnnotatedType 的注解存储在 Kotlin Metadata 注解中,只能通过 Kotlin 反射访问。
更新:
自 Kotlin 1.4.0 起,编译器会按预期编写类型注解。
英文:
Annotations of AnnotatedType of Kotlin fields are stored with Kotlin Metadata annotation and can be accessed only by Kotlin Reflection.
Update:
Since Kotlin 1.4.0, the compiler writes type annotations as it is expected.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论