Annotation中annotationType和getclass的区别

概述

JDK中获取注解时,返回的都是Annotation类型,如下(截取自JDK源码)

public <A extends Annotation> A getAnnotation(Class<A> annotationClass)

当获取到Annotation的实例后,可以通过getClass(从Object继承而来)和annotationType(Annotation接口中的方法)获取到相关的Class。下面阐述一下两者的区别,以下内容为自己的推断,并不是通过翻阅源码获得的结论。

getClass与annotationType对比

测试代码:

SpringBootApplication a = DemoApplication.class.getAnnotation(SpringBootApplication.class);
Class<? extends Annotation> b = a.annotationType();
Class<?> c = a.getClass();
ComponentScan d = b.getAnnotation(ComponentScan.class);
ComponentScan e = c.getAnnotation(ComponentScan.class);

测试结果:

在这里插入图片描述

从图中可以看出:

  • getClass获取到的是一个代理类对象,通过该对象,通过该对象可以获取到注解中定义的属性。
  • annotationType获取到的是注解本身(Class对象),通过该接口可以实现获取注解上的注解,比如:上面通过annotationType可以获取到SpringBootApplication 注解上的ComponentScan注解信息

推论

  • 注解是一类特殊的接口,其定义了注解实例对象(通过getAnnotation获取的类上面的注解信息)能够拥有的属性,它本身也有Class属性。
  • getAnnotation方法获取到的注解实例有自己的类型,它是JDK利用代理技术实现了注解(注解是一类特殊的接口)的实现类,并不是注解类型本身

上面说的有点绕,如果把注解当做接口来看,那么就会有接口、实现类、实现类的对象;分别对应上述代码中的

  • a.annotationType()
  • Class<?> c = a.getClass();
  • SpringBootApplication a = DemoApplication.class.getAnnotation(SpringBootApplication.class);
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
首先,需要获取到需要修改注解的类的Class对象。然后,通过该Class对象的getDeclaredField()方法获取需要修改注解的字段,再通过该字段的getAnnotations()方法获取所有注解,接着遍历注解数组,找到需要修改的注解,使用Java反射的Proxy.newProxyInstance()方法创建一个代理对象,并在代理对象实现InvocationHandler接口,在invoke()方法修改注解的值。最后,通过反射调用setAnnotation()方法将修改后的注解设置回原字段。 以下是示例代码: ``` // 获取Class对象 Class<?> clazz = MyClass.class; // 获取需要修改注解的字段 Field field = clazz.getDeclaredField("myField"); // 获取所有注解 Annotation[] annotations = field.getAnnotations(); // 遍历注解数组 for (Annotation annotation : annotations) { // 判断是否需要修改的注解 if (annotation.annotationType() == MyAnnotation.class) { // 创建代理对象 Object proxy = Proxy.newProxyInstance(annotation.getClass().getClassLoader(), new Class[]{annotation.annotationType()}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 修改注解的值 if (method.getName().equals("value")) { return "new value"; } else { return method.invoke(annotation, args); } } }); // 将修改后的注解设置回原字段 field.setAnnotation((MyAnnotation) proxy); } } ``` 需要注意的是,修改注解的值是在代理对象的invoke()方法实现的,需要根据注解的属性名称进行判断和修改。同时,由于注解是不可变的,因此需要使用代理对象来动态修改注解的属性值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值