Java - 如何在单个参数中获取多个注释?
Java - How to get multiple annotations in a single parameter?
如果我有这样的方法:
testLink(@LinkLength(min=0, max=5) List<@LinkRange(min=5, max=9) Integer> link) { ... }
如何同时获得@LinkLength 和@LinkRange 注解?
我假设您想反射性地访问这些注释。这是一个例子:
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")
使用的方法如下:
Class#getMethod(String,Class...)
- 只会得到一个public方法。要获得非 public 方法,请参阅
Class#getDeclaredMethod(String,Class...)
。
-
Method
从 Executable
扩展而来。
AnnotatedParameterizedType#getAnnotatedActualTypeArguments()
AnnotatedElement#getAnnotation(Class)
Method
、Parameter
、AnnotatedType
(以及其他类型)都继承了AnnotatedElement
.
上面的例子充分利用了关于bar
方法的知识。换句话说,我知道只有一个参数,我知道 Parameter#getAnnotatedType()
会 return AnnotatedParameterizedType
,而且我知道参数化类型有一个类型参数。当反射扫描任意 class 时,这些信息不会提前知道,这意味着您必须添加适当的检查并且只在适当的时候执行某些操作。例如:
AnnotatedType type = parameter.getAnnotatedType();
if (type instanceof AnnotatedParameterizedType) {
// do something...
}
如果我有这样的方法:
testLink(@LinkLength(min=0, max=5) List<@LinkRange(min=5, max=9) Integer> link) { ... }
如何同时获得@LinkLength 和@LinkRange 注解?
我假设您想反射性地访问这些注释。这是一个例子:
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")
使用的方法如下:
Class#getMethod(String,Class...)
- 只会得到一个public方法。要获得非 public 方法,请参阅
Class#getDeclaredMethod(String,Class...)
。
- 只会得到一个public方法。要获得非 public 方法,请参阅
-
Method
从Executable
扩展而来。
AnnotatedParameterizedType#getAnnotatedActualTypeArguments()
AnnotatedElement#getAnnotation(Class)
Method
、Parameter
、AnnotatedType
(以及其他类型)都继承了AnnotatedElement
.
上面的例子充分利用了关于bar
方法的知识。换句话说,我知道只有一个参数,我知道 Parameter#getAnnotatedType()
会 return AnnotatedParameterizedType
,而且我知道参数化类型有一个类型参数。当反射扫描任意 class 时,这些信息不会提前知道,这意味着您必须添加适当的检查并且只在适当的时候执行某些操作。例如:
AnnotatedType type = parameter.getAnnotatedType();
if (type instanceof AnnotatedParameterizedType) {
// do something...
}