2

How can I pass an annotion instance to a function?

I would like to call the java method AbstractCDI.select(Class<T> type, Annotation... qualifiers). But I don't know how to pass an annotation instance to this method.

Calling the constructor like cdiInstance.select(MyClass::javaClass, MyAnnotation()) is not allowed and the @Annotation-Syntax cdiInstance.select(MyClass::javaClass, @MyAnnotation) is not allowed as parameter, too. How can I archive this?

Roland
  • 22,259
  • 4
  • 57
  • 84
Marc von Renteln
  • 1,229
  • 15
  • 34

2 Answers2

2

When working with CDI you usually also have AnnotationLiteral available or at least you can implement something similar rather easy.

If you want to select a class using your annotation the following should do the trick:

cdiInstance.select(MyClass::class.java, object : AnnotationLiteral<MyAnnotation>() {})

Or you may need to implement your specific AnnotationLiteral-class if you require a specific value. In Java that would work as follows:

class MyAnnotationLiteral extends AnnotationLiteral<MyAnnotation> implements MyAnnotation {
    private String value;

    public MyAnnotationLiteral(String value) {
        this.value = value;
    }
    @Override
    public String[] value() {
        return new String[] { value };
    }
 }

In Kotlin however, you can't implement the annotation and extend AnnotationLiteral or maybe I just did not see how (see also related question: Implement (/inherit/~extend) annotation in Kotlin).

If you rather want to continue using reflection to access the annotation then you should probably rather use the Kotlin reflection way instead:

ClassWithAnno::class.annotations
ClassWithAnno::methodWithAnno.annotations

Calling filter, etc. to get the Annotation you desire or if you know there is only one Annotation there, you can also just call the following (findAnnotation is an extension function on KAnnotatedElement):

ClassWithAnno::class.findAnnotation<MyAnnotation>()
ClassWithAnno::methodWithAnno.findAnnotation<MyAnnotation>()
Roland
  • 22,259
  • 4
  • 57
  • 84
  • Thank you! AnnotationLiteral was exactly what I searched for! – Marc von Renteln Aug 17 '18 at 08:26
  • You are welcome! Note, that I added also a question regarding implementation of `AnnotationLiteral` for cases where you need to specify custom values (e.g. to narrow which qualifier should be taken). If you don't require that you are lucky and `AnnotationLiteral` will work as is. If you do, then you may need to use a Java implementation as workaround for now as Kotlin doesn't seem to support it. – Roland Aug 17 '18 at 09:21
0

One could annotate a method or field with the annotation an get it per Reflection:

this.javaClass.getMethod("annotatedMethod").getAnnotation(MyAnnotation::class.java)

Or According to Roland's suggestion the kotlin version of the above:

MyClass::annotatedMethod.findAnnotation<MyAnnotation>()!!

As suggested by Roland for CDI it is better to use AnnotationLiteral (see his post).

Marc von Renteln
  • 1,229
  • 15
  • 34