问题
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 fromExecutable
.
Parameter#getAnnotatedType()
AnnotatedParameterizedType#getAnnotatedActualTypeArguments()
AnnotatedElement#getAnnotation(Class)
Method
,Parameter
, andAnnotatedType
(and other types) all inheritAnnotatedElement
.
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