通过反射获取注解的属性值(内含源代码)
源代码下载链接地址:
https://download.csdn.net/download/weixin_46411355/87554543
目录
- 通过反射获取注解的属性值(内含源代码)
- `源代码下载链接地址:`[https://download.csdn.net/download/weixin_46411355/87554543](https://download.csdn.net/download/weixin_46411355/87554543)
- 1、获取类上注解的值
- 1.1 定义注解类
- 1.2 定义使用注解的类
- 1.3 测试类
- 1.4 测试结果
- 2、获取属性变量上注解的值
- 2.1 定义注解类
- 2.2 定义使用注解的类
- 2.3 定义测试类
- 2.4 测试结果
- 3、获取方法上注解的值
- 3.1 定义注解类
- 3.2 定义使用注解的类
- 3.3 测试类
- 3.4 测试效果
- 4、 获取" 方法参数 " 上注解的值
- 4.1 定义注解类
- 4.2 定义使用注解的类
- 4.3 测试类
- 总结:
1、获取类上注解的值
1.1 定义注解类
package com.tedu.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Orange {
String getName();
String getValue();
}
1.2 定义使用注解的类
package com.tedu.use_anno;
import com.tedu.anno.Orange;
@Orange(getName = "3333",getValue ="4444")
public class ParameterTest {
}
1.3 测试类
package com.tedu.test;
import com.tedu.anno.Orange;
import com.tedu.use_anno.ParameterTest;
public class GetAnnoPropertyAtClass {
public static void main(String[] args) {
//通过反射获取类
Class clazz = ParameterTest.class;
//判断Orange是否是一个注解
if(clazz.isAnnotationPresent(Orange.class)){
//获取类上的注解
Orange gettedAnnptation = (Orange) clazz.getAnnotation(Orange.class);
System.out.println("类上的注解获取到第一个:"+gettedAnnptation.getName()+",第二个:"+gettedAnnptation.getValue());
}
}
}
1.4 测试结果
2、获取属性变量上注解的值
2.1 定义注解类
package com.tedu.anno;
import jdk.nashorn.internal.ir.annotations.Reference;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Banana {
String length();
String price();
}
2.2 定义使用注解的类
package com.tedu.use_anno;
import com.tedu.anno.Banana;
public class ParameterNameTest {
@Banana(length = "6666",price="888")
String something = "other information";
}
2.3 定义测试类
package com.tedu.test;
import com.tedu.anno.Banana;
import com.tedu.use_anno.ParameterNameTest;
import java.lang.reflect.Field;
public class GetAnnoPropertyAtField {
public static void main(String[] args) {
//通过反射获取类
Class clazz = ParameterNameTest.class;
//获取属性变量上的注解的值
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if(field.isAnnotationPresent(Banana.class)){
Banana bananaAnnotation = field.getAnnotation(Banana.class);
System.out.println("属性变量上的注解值获取到第一个:"+bananaAnnotation.length()+
"第二个:"+bananaAnnotation.price());
}
}
}
}
2.4 测试结果
3、获取方法上注解的值
3.1 定义注解类
package com.tedu.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Apple {
String color();
String number();
}
3.2 定义使用注解的类
package com.tedu.use_anno;
import com.tedu.anno.Apple;
public class ParameterNameTest {
@Apple(color = "红色",number = "5555")
public void method1(){
}
}
3.3 测试类
package com.tedu.test;
import com.tedu.anno.Apple;
import com.tedu.use_anno.ParameterNameTest;
import java.lang.reflect.Method;
public class GetAnnoPropertyAtMethod {
public static void main(String[] args) {
Class clazz = ParameterNameTest.class;
//获取"方法"上的注解的值
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
if(method.isAnnotationPresent(Apple.class)){
Apple appleAnnotation = method.getAnnotation(Apple.class);
System.out.println("方法上的注解值获取到第一个:"+appleAnnotation.color()+",第二个"+appleAnnotation.number());
}
}
}
}
3.4 测试效果
4、 获取" 方法参数 " 上注解的值
4.1 定义注解类
package com.tedu.anno;
import java.lang.annotation.*;
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Cherry {
String value();
}
4.2 定义使用注解的类
package com.tedu.use_anno;
import com.tedu.anno.Cherry;
public class ParameterNameTest {
public void method2(@Cherry("1111") String param1, @Cherry("2222") String param2){
System.out.println(param1+param2);
}
}
4.3 测试类
> package com.tedu.test;
import com.tedu.anno.Cherry;
import com.tedu.use_anno.ParameterNameTest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
public class GetAnnoPropertyValueAtMethodParameter {
public static void main(String[] args) throws NoSuchMethodException {
Class clazz = ParameterNameTest.class;
//获取“方法参数”上的注解的值
Method method = clazz.getDeclaredMethod("method2", String.class, String.class);
String[] parameterNames = getMethodParameterNamesByAnnotation(method);
System.out.println("\"方法参数\"上的注解值获取到"+ Arrays.toString(parameterNames));
}
/**
* 获取给 "方法参数" 注解的值
* @param method 要获取参数名的方法
* @return 按参数顺序排列的参数名列表
*/
public static String[] getMethodParameterNamesByAnnotation(Method method) {
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
if (parameterAnnotations == null || parameterAnnotations.length == 0) {
return null;
}
String[] parameterNames = new String[parameterAnnotations.length];
int i = 0;
for (Annotation[] parameterAnnotation : parameterAnnotations) {
for (Annotation annotation : parameterAnnotation) {
if (annotation instanceof Cherry) {
Cherry param = (Cherry) annotation;
parameterNames[i++] = param.value();
}
}
}
return parameterNames;
}
}
测试效果:
总结:
主要使用的API是Class类中的实现接口AnnotatedElement
的方法
isAnnotationPresent
— 检测该元素是否被对应注解修饰
default boolean isAnnotationPresent(Class extends Annotation> annotationClass) { return getAnnotation(annotationClass) != null;
}
getAnnotation --- 获取注解对象
T getAnnotation(Class annotationClass);