Java - Как получить несколько аннотаций в одном параметре? - PullRequest
1 голос
/ 01 марта 2020

Если у меня есть такой метод:

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

Как получить аннотации @LinkLength и @LinkRange?

1 Ответ

3 голосов
/ 01 марта 2020

Полагаю, вы хотите рефлексивно получить доступ к этим аннотациям. Вот пример:

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));
  }
}

, который выводит следующее:

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

Вот методы, используемые:

В приведенном выше примере используются совершенные знания о методе bar. Другими словами, я знал, что есть один параметр, я знал, что Parameter#getAnnotatedType() вернет AnnotatedParameterizedType, и я знал, что параметризованный тип имеет один аргумент типа. Эта информация не будет известна заранее при рефлексивном сканировании произвольного класса, а это означает, что вам придется добавлять соответствующие проверки и выполнять только определенные действия, когда это необходимо. Например:

AnnotatedType type = parameter.getAnnotatedType();
if (type instanceof AnnotatedParameterizedType) {
  // do something...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...