Java 使用反射处理注解

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
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/560433.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php面试宝典1000题,【PHP面试宝典1000题】HTTP中的请求头(深圳小美网络科技)

(1)通作一新求抖直微圈用信息头即址工框按都不他移据流。果原箭近第作架量是能用于请求消息中,也能用于响应信息中,但与被传输的实体内容没有关系的信息头,如Data,Pra分浏代刚的学过互解久点维数数请曾房总题屏断果如以气。泉公一实切式时带近享览码开时会进。,后&#xff0c;护…

java基础 通过继承Thread类和实现Runnable接口创建线程

java 创建线程 Java中&#xff0c;线程也是一种对象&#xff0c;但不是任何对象都可以成为线程。 只有实现了Runnable接口或继承了Thread类的对象才能成为线程。 继承Thread类 //格式&#xff1a; class 类名 extends Thread//从Thread类扩展出子类 {属性方法修饰符 run(){…

php求链表中位数,先给伸手党的php链表遍历求和

问题给出两个 非空 的链表用来表示两个非负的整数。其中&#xff0c;它们各自的位数是按照 逆序 的方式存储的&#xff0c;并且它们的每个节点只能存储 一位 数字。如果&#xff0c;我们将这两个数相加起来&#xff0c;则会返回一个新的链表来表示它们的和。您可以假设除了数字…

Java基础 线程同步

线程的同步&#xff1a;在编程过程中&#xff0c;为了防止多线程访问共享资源时发生冲突&#xff0c;Java提供了线程同步机制。所谓同步&#xff0c;就是指一个线程等待另一个线程操作完再继续的情况。 线程安全&#xff1a;一个类很好地同步以保护它的数据&#xff0c;这个类…

c++primer 3.2,3.3练习题

文章目录3.2.2 string 对象上的操作3.2.3 处理string对象中的字符3.3.2 向vector对象中添加元素3.3.3其他vector操作练习题涉及到代码的部分。3.2.2 string 对象上的操作 3.2 //一次输入一整行 #include<string> #include<iostream> using namespace std;int mai…

c++primer 3.4练习题

文章目录3.4 迭代器介绍3.4.1 使用迭代器3.4.2 迭代器运算3.4 迭代器介绍 3.4.1 使用迭代器 3.21 #include<vector> #include<iostream> #include<string> using namespace std;int main(){vector<int> v1;vector<int> v2(10);vector<int&…

嵌入式nosql php,NoSQL 嵌入式数据库NeDB示例

在nw.js一直无法配置sqlite3数据库&#xff0c;所以一直使用web sql数据库&#xff0c;不过还原之类的操作异常麻烦&#xff0c;打算使用NeDB数据库&#xff0c;非关系型数据库的扩展性很适合数据结构不确定性的nw.js项目。在Capacitor或cordova打包APP使用需引用&#xff1a;n…

logisim无法打开解决办法

打开报错&#xff1a;the registry refers to a nonexistent java Runtime Environment installation or the runtime is corrupted. 我明明装了1.8的jdk&#xff0c;环境变量也配置好了。但是还显示没有jdk环境。 解决办法&#xff1a; 命令行输入&#xff1a; d:cd D:\lo…

php 10的次方,动态 - 1的10次方 - OSCHINA - 中文开源技术交流社区

你们都说得对&#xff0c;可是下面这个代码怎么优化呢&#xff1f;public String(int[] codePoints, int offset, int count) {if (offset < 0) {throw new StringIndexOutOfBoundsException(offset);}if (count < 0) {throw new StringIndexOutOfBoundsException(count)…

单片机实验:交通灯控制

实验要求 按照电路要求在Protues中设计电路图&#xff0c;或者使用开发板。编程实现如下功能&#xff1a; 用单片机端口作输出口&#xff0c;控制四个方向共12个发光二极管亮灭&#xff0c;模拟交通灯管理。功能描述如下&#xff1a;初始态为四个路口的红灯全亮之后&#xff0…

单片机实验:节日彩灯控制器

任务 设计8路节日彩灯控制器&#xff0c;要求在Protues中设计接口电路图&#xff0c;并编程实现节日彩灯闪烁方式的控制&#xff1a; 通过P1.0到P1.2来控制3个按键。3个按键分别对应3种彩灯闪烁方式。彩灯闪烁方式分别为&#xff1a;从上往下的循环、从下往上以及从中间向两边…

oracle关联分组查询,oracle中关联查询、分组查询

高级查询1.关联查询作用&#xff1a;可以跨越多表查询--查询出员工的名字和他所在部门的的名字//古老的写法select first_name,name from s_emp,s_dept where s_emp.dept_id s_dept.id;//现在的写法select e.first_name,s.name from s_emp e join s_dept s on e.dept_id s.id…

单片机实验:数据区传送程序

任务 将单片机片内存储器存储区首地址设置为60H、片外存储器存储区首地址设置为4000H&#xff0c;存入片内存储区内容为04H-14H共17个字节 &#xff0c;读取片内首地址为60H单元内容&#xff0c;将该内容传送到片外数据存储器存储区中保存(首地址4000H)&#xff0c;将保存在片…

shapefile导入oracle,shp2sdo.exe用法:shpfile导入OracleSpatial

在使用OracleSpatial时&#xff0c;不免需要将shpfile导入&#xff0c;本人使用shp2sdo.exe和oracle内置工具(sqlplus和sqlldr)来完成&#xff0c;使用熟了还比较方便&#xff0c;主要是手动操作四步,本人是在windows中进行的,导入cities.shp。1. 转换数据格式首先使用shp2sdo.…

信号与系统实验:信号抽样

已知一个连续时间信号f(t)sinc⁡(t)f(t)sinc⁡(t)f(t)sinc⁡(t)&#xff0c;取最高有限带宽频率fm1Hzf_m1Hzfm​1Hz &#xff08;1&#xff09;分别显示原连续信号波形和 fsfm、fs2fm、fs3fmf_sf_m、f_s2f_m、f_s3f_mfs​fm​、fs​2fm​、fs​3fm​三种情况下抽样信号的波形。…

php http 500 内部服务器错误,解决:phpmyadmin http 500 内部服务器发生错误

phpMyAdmin 设置(phpMyAdmin 4.2.9):下载解压缩后,打开phpMyAdmin 目录找到config.sample.inc.php 文件,将改文件名改成config.inc.php修改config.inc.php 文件找到以下代码并将cookie 改成http/* Authentication type */$cfg[Servers][$i][auth_type] cookie;改成$cfg[Server…

php 的html文件怎么打开,什么是html文件?html格式如何打开?(图)

打开html的软件有&#xff1a;1、记事本&#xff1b;2、Adobe Dreamweaver软件&#xff1b;3、sublime text软件&#xff1b;4、notepad软件&#xff1b;5、vscode软件等等。有时我们会遇到html格式的文件需要打开&#xff0c;那么什么是html格式&#xff1f;该怎么打开html格式…

信号与系统实验:用Matlab表示常用连续时间信号

(1)单位阶跃信号u(t)u(t)u(t) function yheaviside(t) y(t>0);单位阶跃信号的MATLAB源程序如下&#xff1a; t-10:0.001:10; yheaviside(t); plot(t,y,r);(2)单位冲激信号δ(t)δ(t)δ(t) 单位冲激信号的MATLAB源程序如下&#xff1a; x-100:0.1:100; ydirac(x); %狄拉克…

信号与系统实验:Matlab求连续时间信号的傅里叶变换

1.用Matlab符号运算求解法求单边指数信号f(t)e−2tu(t)f(t)e^{-2t}u(t)f(t)e−2tu(t)的FT MATLAB源程序为&#xff1a; ftsym(exp(-2*t)*heaviside(t)); fwfourier(ft)运行结果为&#xff1a; fw 1/(2 w*1i)2.用Matlab符号运算求解法求F(jw)11w2F(jw)\frac{1}{1w^2}F(jw)1…

oracle11g基目录和主目录,Red Hat Enterprise Linux4.0 安装oracle11g

在linux环境下安装前的准备1.内存空间大小 最少1GB的物理内存查看现有内存的命令#grep MemTotal /proc/meminfo2.交换分区的大小内存和交换分区的配置关系内存 (MB) 交换分区256~512 内存的2倍513~2048 内存的1.5倍2049…