Java 使用反射处理注解

自定义注解的格式:

[public|final] @interface 注解名//@interface 表明:这是一个自定义注解
{注解元素//注解元素 是无参数的方法
}// 注解元素的格式:
数据类型 注解元素名() [default 默认值]

例子:

//自定义注解:
package test;import java.lang.annotation.*;
@Target({ElementType.TYPE, ElementType.METHOD})
//注解作用于类和方法的声明上
@Retention(RetentionPolicy.RUNTIME)
//注解在运行时有效
public @interface UseAnno {String value() default "user";
}//使用自定义注解UseAnno
package test;
@UseAnno//在类上使用注解
public class AnnoC {@UseAnno("注解作用在方法上")//在方法上使用注解public void method() {System.out.println("在方法上使用注解");}
}

使用反射处理注解

利用反射可以在运行时动态获取类的相关信息,如类的方法、属性、构造方法。还可以创建对象、调用方法等。利用反射也可以获取注解的相关信息。

反射是在运行时获取相关信息的,要使用反射获取注解的相关信息,这个注解必须是用@Retention(RetentionPolicy.RUNTIME)声明的。

java.lang.reflect.AnnotatedElement接口定义了使用反射读取注解信息的方法:

Annotation getAnnotation(Class annotationType)
//若存在该元素指定类型的注解,则返回这些注解,否则返回null。
Annotation[] getAnnotations()
//返回此元素上存在的所有注解。包括继承的
Annotation[] getDeclaredAnnotations()
//返回该元素上存在的所有注解,不包括继承的。/*对于getAnnotations()和getDeclaredAnnotations():如果没有注释直接存在于此元素上,则返回长度为零的一个数组。该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。*/
java.lang.Package.isAnnotationPresent:
public boolean isAnnotationPresent(类<? extends Annotation> annotationClass)//若指定类型的注解存在于此元素上,则返回true,否则返回false
例:
aField.isAnnotationPresent(ApplianceMaker.class)
//意思是,判断aField字段的注解是不是ApplianceMaker 类型
//自定义注解:
package test;import java.lang.annotation.*;
@Target({ElementType.TYPE, ElementType.METHOD})
//注解作用于类和方法的声明上
@Retention(RetentionPolicy.RUNTIME)
//注解在运行时有效
public @interface UseAnno {String value() default "user";
}//使用自定义注解UseAnno
package test;
@UseAnno//在类上使用注解
public class AnnoC {@UseAnno("注解作用在方法上")//在方法上使用注解public void method() {System.out.println("在方法上使用注解");}
}
package test;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
//利用反射获取注解的值
public class ReflectAnno {public static void main(String[] args) {try {Class c = Class.forName("test.AnnoC");//获取  使用注解的类  AnnoC 的Class对象cClass cUse = Class.forName("test.UseAnno");//获取  注解类UseAnno  的Class对象cUserAnnotation anno = c.getAnnotation(cUse);//获取AnnoC类上使用的cUse注解  annoif(anno != null) {UseAnno a = (UseAnno) anno;System.out.println("AnnoC类上的注解: " + a.value());}Method m = c.getDeclaredMethod("method");Annotation an = m.getAnnotation(cUse);//获取method()方法上使用的cUse注解  anif(an != null) {UseAnno a = (UseAnno) an;System.out.println("method()方法上的注释: " + a.value());}}catch(Exception e) {e.printStackTrace();}}
}
/*输出
AnnoC类上的注解: user
method()方法上的注释: 注解作用在方法上
*/
//例子2
package test;
import java.lang.annotation.*;
import java.lang.reflect.*;
@Retention(RetentionPolicy.RUNTIME) // 元注解,运行时保留注解,必须有,否则注解值读不出
@interface ApplianceMaker // 定义注解
{// 定义注解元素,都有默认值public String type() default "TV";public String id() default "001";public String maker() default "PandaTv";public String address() default "BJ";
}@Retention(RetentionPolicy.RUNTIME)
@interface ApplianceSaler // 定义注解
{public String name() default "TM";public String id() default "001";public String address() default "HK";
}@Retention(RetentionPolicy.RUNTIME)
@interface AppliancePrice // 定义注解
{// 注解元素只有一个,名为valuepublic int value() default 1200;
}class Appliance {// 为域maker 加注解,给部分元素赋值,其余用默认值// 如果注解元素都用默认值,则直接写@ApplianceMaker@ApplianceMaker(type = "电脑", id = "201")public String maker;@ApplianceSaler(name = "JD", id = "222", address = "WH")public String saler; // 域有注解@AppliancePrice(999) // 也可以写成"value=999",因为只有一个,此处只写出值即可public int price; // 域有注解public void setMaker(String m) {maker = m;}public String getMaker() {return maker;}public void setSaler(String saler) {this.saler = saler;}public String getSaler() {return saler;}public void setPrice(int price) {this.price = price;}public int getPrice() {return price;}
}public class Test {public static void main(String args[]) {System.out.println(readAnnotation(Appliance.class));}// 读注解信息private static String readAnnotation(Class aClass) {String maker = "制造商:";String saler = "销售商:";String price = "价格:";Field fields[] = aClass.getDeclaredFields(); // 获取Appliance 类的所有字段for (Field aField : fields) // 对每一个字段判断其注解的类型{// 字段的注解是ApplianceMaker 类型if (aField.isAnnotationPresent(ApplianceMaker.class)) {ApplianceMaker aMaker; // 声明一个注解变量// 调用getAnnotation()方法获得在aField 域上的注解“实例”aMaker = (ApplianceMaker) aField.getAnnotation(ApplianceMaker.class);maker += aMaker.type() + " "; // 获取type 元素的值,其余与此相同maker += aMaker.id() + " ";maker += aMaker.maker() + " ";maker += aMaker.address() + "\n";}// 字段的注解是ApplianceSaler 类型else if (aField.isAnnotationPresent(ApplianceSaler.class)) {ApplianceSaler aSaler;aSaler = (ApplianceSaler) aField.getAnnotation(ApplianceSaler.class);saler += aSaler.name() + " ";saler += aSaler.id() + " ";saler += aSaler.address() + "\n";}// 字段的注解是AppliancePrice 类型else if (aField.isAnnotationPresent(AppliancePrice.class)) {AppliancePrice thePrice;thePrice = (AppliancePrice) aField.getAnnotation(AppliancePrice.class);price += thePrice.value();}}return maker + saler + price;}
}
/*输出:
制造商:电脑 201 PandaTv BJ
销售商:JD 222 WH
价格:999
*/

Java 使用反射处理注解相关推荐

  1. Java:反射和注解从入门到放弃

    以下是两个讲得通俗易懂的注解与反射例子,敬请参考! 注解: 秒懂,Java 注解 (Annotation)你可以这样学 反射: Java反射:框架设计的灵魂

  2. java注解的反射_Java注解与反射

    概要 本文主要是总结Java注解与反射的相关知识,加深自己对Java类动态语言的理解,同时为日后学习Spring打下基础. 注解: 什么是注解 Annotation的作用 不是程序本身,但是可以对程序 ...

  3. Java学习笔记7-2——注解与反射

    目录 理解 Class 类并获取 Class 实例 Class类 获取 Class 类的实例 哪些类型可以有Class对象 所有类型的Class对象 从内存角度分析类加载[重点] 类加载的过程 什么时 ...

  4. java运行时读取注解_Java自定义注解和运行时靠反射获取注解

    转:1.Annotation的工作原理: JDK5.0中提供了注解的功能,允许开发者定义和使用自己的注解类型.该功能由一个定义注解类型的语法和描述一个注解声明的语法,读取注解的API,一个使用注解修饰 ...

  5. 【Java】Junit、反射和注解的笔记

    1 Junit 黑盒测试:不需要写代码,给输入值,看程序输出是否符合期望 白盒测试:需要写代码,关注程序具体的执行流程 Junit -> 白盒测试 步骤 定义一个测试类(测试用例) [命名:类名 ...

  6. java 注解与反射_Java注解与反射直接上手

    什么是注解(Annotation) 注解顾名思义为注释.讲解,可以理解为一种标签或标记,可以用在类.方法或者域上.向类.方法等添加注解,相当于给他们贴上了一层标签. 注解使用 在使用注解时,在类名.方 ...

  7. 【JAVA SE】第十七章 反射、注解与Spring事务底层原理

    第十七章 反射.注解与Spring事务底层原理 文章目录 第十七章 反射.注解与Spring事务底层原理 一.反射 1.简介 2.意义 3.缺点 4.应用场景 5.反射技术的使用 二.注解 1.概念 ...

  8. Java基础13:反射与注解详解

    Java基础13:反射与注解详解 什么是反射? 反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性. Orac ...

  9. java 获取类的注解_Java 自定义注解通过反射获取类、方法、属性上的注解

    反射 JAVA中的反射是运行中的程序检查自己和软件运行环境的能力,它可以根据它发现的进行改变.通俗的讲就是反射可以在运行时根据指定的类名获得类的信息. 注解的定义 注解通过 @interface 关键 ...

最新文章

  1. oracle+root+密码忘记,教您如何修复各种UNIX系统下root密码
  2. Sun x4500作为文件服务器的调优
  3. 调用微信和支付宝调三方接口扫描二维码?
  4. Java枚举根据key获取value
  5. 统计vs机器学习,数据领域的“少林和武当”!
  6. linux进程cpu时间片,能讲一下在Linux系统中时间片是怎么分配的还有优先级的具体算法是...
  7. linux内核编译的image,内核编译时生成uImage的办法
  8. java开发过程中几种常用算法
  9. css3 transition 和 animation实现走马灯
  10. 1650 cuda版本_英伟达新卡曝光:GTX1650 GDDR6出现第三种版本,比新冠变异还快
  11. 考拉Android统一弹框
  12. SqlServer存储过程基础
  13. java迷宫算法继承_求Java关于迷宫的算法(用栈实现)
  14. 基于RV1126平台imx291分析 --- media部件注册 mipi csi
  15. coc机器人苹果_警察机器人绳索英雄
  16. 毕业设计-基于微信小程序房屋安全管理系统
  17. R语言绘制Kaplan-Meier生存曲线
  18. 梭杆菌(Fusobacterium)——共生菌,机会菌,癌杆菌
  19. DIY空气检测仪:攀藤G5ST分析仪
  20. 百度网盘撸用户羊毛是怎么一回事

热门文章

  1. JDBC中使用PreparedStatement执行SQL语句并管理结果集
  2. synchronized同步方法概述
  3. 自动图片轮播php源码,js实现自动图片轮播代码
  4. html中最右边,html – 如何获得最右边的列填充剩余空间?
  5. java变量用来干嘛_Java
  6. vue如何把数组转为json数组_vue.js,_vuejs Ajax取得一个数据json数组,vue.js - phpStudy...
  7. 计算机有必要报英语四级吗,我已工作了,现在有必要去考英语四级吗?还是 – 手机爱问...
  8. c++ string类_C++|细说STL string类概貌及底层细节
  9. oracle1461,Oracle 10.2.0.3的ORA-1461错误
  10. linux运行搜狗拼音,Linux 搜狗输入法的安装(Ubuntu版)