Reputation: 317
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:
a
with @JvmField
. This did not change the behaviour.@Target(AnnotationTarget.TYPE)
@Retention(AnnotationRetention.RUNTIME)
annotation class KotlinAnnot
val a: @KotlinAnnot Int = 5
Did not fix the problem.
Is this a kotlin bug? Do type use annotations not exist in kotlin, or is the syntax different? What am I doing wrong?
Thanks.
Upvotes: 2
Views: 752
Reputation: 2453
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.
Upvotes: 1