Java - How to get multiple annotations in a single parameter?

心不动则不痛 提交于 2020-04-07 07:09:31

问题


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?


回答1:


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:

  • Class#getMethod(String,Class...)

    • Will only get a public method. To get a non-public method see Class#getDeclaredMethod(String,Class...).
  • Executable#getParamaeters()

    • Method extends from Executable.
  • Parameter#getAnnotatedType()

  • AnnotatedParameterizedType#getAnnotatedActualTypeArguments()

  • AnnotatedElement#getAnnotation(Class)

    • Method, Parameter, and AnnotatedType (and other types) all inherit AnnotatedElement.

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...
}


来源:https://stackoverflow.com/questions/60477426/java-how-to-get-multiple-annotations-in-a-single-parameter

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!