Kotlin and Java Annotations


#1

Hello,

I’m having a little trouble with relfection in Kotlin.
The project uses some Neo4J annotations which I would like to access.
A sample class looks like this:

class Foo {

 @Property(name = "BAR")
 val bar = "bar"

}

Now to get the name specified in the annotation the first step would be to get the annotation itself:

Foo::bar.annotations

this however always returns an empty list in my case. Might the problem be the need to specifiy wether or not the annotations should be visible at runtime? If so could someone point me to the right direction as to where I should do this?


#2

You may need to specify which part of the generated code for the val needs to be annotated: https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets


#3

Thank you for your fast reply. I have tried as you suggested but to no avail:

The source of the annotation says its target should be an field:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
@Inherited
public @interface Property {
    String NAME = "name";

    String name() default "";
}

So I changed the annotation to

@field:Property(name="BAR")
val bar = "bar"

Sadly this still returns an empty list.


#4

I think the problem might be that Foo::bar.annotations only covers @property:*** annotations and doesn’t include @field:*** annotations. And you can see that the targets of @interface Property are fields only, and not properties – @Target({ElementType.FIELD}). (I assume, that you even can’t specify the kotlin-property target in java-annotations, since java should be unaware of all the kotlin specific terms.)

To access the @field:*** you can try something like: Foo::bar.javaField.getAnnotation(Property::class.java) or Foo::bar.javaField.getAnnotations() or Foo::bar.javaField.annotations, i don’t know if there is a “better” way to achieve that without .java stuff.

Note 1: @Property and @property: are completely separate and unrelated things, see https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets for all possible values of X in @X:***
Note 2: I believe, In this example @Property(name = "BAR") val bar = "bar" is equivalent to @field:Property(name="BAR") val bar = "bar" because the targets of the @interface Property are fields so kottlin will automatically apply the annotation to only the underlying field of the property bar.