1

If I have a method like this:

   testLink(@LinkLength(min=0, max=5) List<@LinkRange(min=5, max=9) Integer> link) { ... }

How do I get both @LinkLength and @LinkRange annotation?

0

1 Answer 1

4

I'm assuming you want to reflectively access these annotations. Here's an example:

package com.example;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedParameterizedType;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.List;

public class Main {

  @Retention(RetentionPolicy.RUNTIME)
  @Target({ElementType.PARAMETER, ElementType.TYPE_USE})
  public @interface Foo {

    String value();
  }

  public static void bar(@Foo("parameter") List<@Foo("type_use") Integer> list) {}

  public static void main(String[] args) throws NoSuchMethodException {
    Method method = Main.class.getMethod("bar", List.class);

    // get annotation from parameter
    Parameter parameter = method.getParameters()[0];
    System.out.println("PARAMETER ANNOTATION = " + parameter.getAnnotation(Foo.class));

    // get annotation from type argument used in parameter
    AnnotatedParameterizedType annotatedType =
        (AnnotatedParameterizedType) parameter.getAnnotatedType();
    AnnotatedType typeArgument = annotatedType.getAnnotatedActualTypeArguments()[0];
    System.out.println("TYPE_USE ANNOTATION  = " + typeArgument.getAnnotation(Foo.class));
  }
}

Which outputs the following:

PARAMETER ANNOTATION = @com.example.Main$Foo(value="parameter")
TYPE_USE ANNOTATION  = @com.example.Main$Foo(value="type_use")

Here are the methods used:

The above example makes use of perfect knowledge about the bar method. In other words, I knew there was one parameter, I knew that Parameter#getAnnotatedType() would return AnnotatedParameterizedType, and I knew that the parameterized type had one type argument. This information won't be known ahead-of-time when reflectively scanning an arbitrary class, meaning you'll have to add appropriate checks and only execute certain actions when appropriate. For example:

AnnotatedType type = parameter.getAnnotatedType();
if (type instanceof AnnotatedParameterizedType) {
  // do something...
}
Sign up to request clarification or add additional context in comments.

1 Comment

Cool. I didn't know about TYPE_USE.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.