高级篇 KZ002.反射读取注解[未封装]
创建自定义注解
package com.hanpang.java; /** * 注解说明: 方法的文档注释 * * @Author: 胖先生 * @Create: 2016-04-27 10:29 * @Home: http://www.cnblogs.com/pangxiansheng/ */ import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Target(ElementType.METHOD) @Inherited @Retention(RetentionPolicy.RUNTIME) public @interface MethodInfo{ String author() default "hanpang"; String date(); int revision() default 1; String comments(); } |
|
复习一下:
package com.hanpang.java; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; /** * 类说明: 完整点的示例 * @Author: 胖先生 * @Create: 2016-04-27 11:24 */ public class AnnotationExample { public static void main(String[] args) { } @Override //什么意思? @MethodInfo(author = "wukong", comments = "重写了toString方法", date = "2016-04-27", revision = 1) public String toString() { return "Overriden toString method"; } @Deprecated //什么意思? @MethodInfo(comments = "该方法已经过时了,被放弃了", date = "2016-04-27") public static void oldMethod() { System.out.println("old method, don't use it."); } @SuppressWarnings({ "unchecked", "deprecation" }) //什么意思? @MethodInfo(author = "bajie", comments = "这里方法里面有警告哟!", date = "2016-04-27", revision = 10) public static void genericsTest() throws FileNotFoundException { List l = new ArrayList(); l.add("abc"); oldMethod(); } } |
复习搞一段落,那么我们现在来学习关于注解的解析操作,如果有时间,我会写一个关于Excel的操作的工具
Java注解解析
我们将使用Java反射机制从一个类中解析注解,请记住,注解保持性策略应该是RUNTIME,否则它的信息在运行期无效,我们也不能从中获取任何数据。
类注解的解析
package com.hanpang.java; import java.lang.annotation.*; /** * 类说明: 定义类的注解 */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface ClassInfo { String value() default ""; String className(); } |
package com.hanpang.java; @ClassInfo(value = "标注在类上",className = "-->com.hanpang.java.AnnotationExample") public class AnnotationExample { public static void main(String[] args) { } } |
类注解 你可以在运行期访问类,方法或者变量的注解信息,下是一个访问类注解的例子: public class AnnotationParsing { public static void main(String[] args) { //1.获取Class Class clz = AnnotationExample.class; //2.获取类的所有注解 Annotation[] annotations = clz.getAnnotations(); //3.进行迭代 for (Annotation annotation : annotations) { //4.判断获取的是否是我们自己写的注解 if (annotation instanceof ClassInfo) { ClassInfo ci = (ClassInfo) annotation; //5.获取属性值,并且进行测试 System.out.println("-->>hanpang<<--value值=" + ci.value() + "," + "当前类=AnnotationParsing.main()"); System.out.println("-->>hanpang<<--className值=" + ci.className() + "," + "当前类=AnnotationParsing.main()"); } } } } |
运行结果为: -->>hanpang<<--className值=-->com.hanpang.java.AnnotationExample,当前类=AnnotationParsing.main() |
你还可以像下面这样指定访问一个类的注解:[如果你已经知道你要对哪个注解进行处理] public class AnnotationParsing { public static void main(String[] args) { //1.获取Class Class clz = AnnotationExample.class; //2.获取你想要的注解 Annotation annotation = clz.getAnnotation(ClassInfo.class); //3.判断是否匹配 if(annotation instanceof ClassInfo){ ClassInfo ci = (ClassInfo) annotation; //获取属性值,并且进行测试 System.out.println("-->>hanpang<<--value值=" + ci.value() + "," + "当前类=AnnotationParsing.main()"); System.out.println("-->>hanpang<<--className值=" + ci.className() + "," + "当前类=AnnotationParsing.main()"); } } } |
方法的注解解析,代码改造如下
package com.hanpang.java; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; @ClassInfo(value = "标注在类上",className = "-->com.hanpang.java.AnnotationExample") public class AnnotationExample { public static void main(String[] args) { } @Override @MethodInfo(author = "wukong", comments = "Main method", date = "2016-04-27", revision = 1) public String toString() { return "Overriden toString method"; } @Deprecated @MethodInfo(comments = "deprecated method", date = "2016-04-27") public static void oldMethod() { System.out.println("old method, don't use it."); } @SuppressWarnings({ "unchecked", "deprecation" }) @MethodInfo(author = "bajie", comments = "Main method", date = "2016-04-27", revision = 10) public static void genericsTest() throws FileNotFoundException { List l = new ArrayList(); l.add("abc"); oldMethod(); } } |
方法注解,解析操作: package com.hanpang.java; import java.lang.annotation.Annotation; import java.lang.reflect.Method; public class AnnotationParsing { public static void main(String[] args) throws NoSuchMethodException { //1.实例化对象 AnnotationExample ae = new AnnotationExample(); //2.获取方法的对象--->>>这里写的有点简单类,如果是全部方法请使用数组 Method method = ae.getClass().getMethod("toString");//方法名 Annotation[] annotations = method.getAnnotations(); for (Annotation annotation : annotations) { if(annotation instanceof MethodInfo){ MethodInfo mi = (MethodInfo)annotation; System.out.println("-->>hanpang<<--author值=" + mi.author() + "," + "当前类=AnnotationParsing.main()"); System.out.println("-->>hanpang<<--commonts值=" + mi.comments() + "," + "当前类=AnnotationParsing.main()"); System.out.println("-->>hanpang<<--date值=" + mi.date() + "," + "当前类=AnnotationParsing.main()"); System.out.println("-->>hanpang<<--revision=" + mi.revision() + "," + "当前类=AnnotationParsing.main()"); } } } } |
运行结果为: -->>hanpang<<--commonts值=Main method,当前类=AnnotationParsing.main() -->>hanpang<<--date值=2016-04-27,当前类=AnnotationParsing.main() -->>hanpang<<--revision=1,当前类=AnnotationParsing.main() |
另一种写法: public class AnnotationParsing { public static void main(String[] args) throws NoSuchMethodException { //1.实例化对象 AnnotationExample ae = new AnnotationExample(); //2.获取方法的对象--->>>这里写的有点简单类,如果是全部方法请使用数组 Method method = ae.getClass().getMethod("toString"); Annotation annotation = method.getAnnotation(MethodInfo.class); if(annotation instanceof MethodInfo){ MethodInfo mi = (MethodInfo)annotation; System.out.println("-->>hanpang<<--author值=" + mi.author() + "," + "当前类=AnnotationParsing.main()"); System.out.println("-->>hanpang<<--commonts值=" + mi.comments() + "," + "当前类=AnnotationParsing.main()"); System.out.println("-->>hanpang<<--date值=" + mi.date() + "," + "当前类=AnnotationParsing.main()"); System.out.println("-->>hanpang<<--revision=" + mi.revision() + "," + "当前类=AnnotationParsing.main()"); } } } |
参数注解解析:
package com.hanpang.java; /** * 新增参数注解 */ import java.lang.annotation.*; @Documented @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface ParameterInfo { String value() default "hanpang"; String desc(); } |
//加大加粗为新增代码部分 import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; @ClassInfo(value = "标注在类上",className = "-->com.hanpang.java.AnnotationExample") public class AnnotationExample { public static void main(String[] args) { } @Override @MethodInfo(author = "wukong", comments = "Main method", date = "2016-04-27", revision = 1) public String toString() { return "Overriden toString method"; } @Deprecated @MethodInfo(comments = "deprecated method", date = "2016-04-27") public static void oldMethod(@ParameterInfo(value = "刘文铭",desc = "测试参数注解解析") String user_name) { System.out.println("old method, don't use it."+user_name); } @SuppressWarnings({ "unchecked", "deprecation" }) @MethodInfo(author = "bajie", comments = "Main method", date = "2016-04-27", revision = 10) public static void genericsTest() throws FileNotFoundException { List l = new ArrayList(); l.add("abc"); oldMethod("悟空"); } } |
package com.hanpang.java; import java.lang.annotation.Annotation; import java.lang.reflect.Method; public class AnnotationParsing { public static void main(String[] args) throws NoSuchMethodException { //1.实例化对象 AnnotationExample ae = new AnnotationExample(); //2.获取方法对象 Method method = ae.getClass().getMethod("oldMethod",java.lang.String.class); //3.获取参数的注解, 注意这里是二维数组 Annotation[][] parameterAnnotations = method.getParameterAnnotations(); //4. Class[] parameterTypes = method.getParameterTypes(); for (int i = 0; i < parameterAnnotations.length; i++) { Annotation[] annotations = parameterAnnotations[i]; Class parameterType = parameterTypes[i]; //继续迭代 for (Annotation annotation : annotations) { if (annotation instanceof ParameterInfo){ ParameterInfo pi = (ParameterInfo)annotation; System.out.println("-->>hanpang<<--数据类型值=" + parameterType.getName() + "," + "当前类=AnnotationParsing.main()"); System.out.println("-->>hanpang<<--pi.value()值=" + pi.value() + "," + "当前类=AnnotationParsing.main()"); System.out.println("-->>hanpang<<--pi.desc()值=" + pi.desc() + "," + "当前类=AnnotationParsing.main()"); } } } } } |
运行结果: -->>hanpang<<--数据类型值=java.lang.String,当前类=AnnotationParsing.main() -->>hanpang<<--pi.value()值=刘文铭,当前类=AnnotationParsing.main() -->>hanpang<<--pi.desc()值=测试参数注解解析,当前类=AnnotationParsing.main() |
注意:需要注意的是 Method.getParameterAnnotations()方法返回一个注解类型的二维数组,每一个方法的参数包含一个注解数组 |
变量注解解析:
package com.hanpang.java; import java.lang.annotation.*; @Documented @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface FieldInfo { String value() default "hanpang"; String desc(); } |
@ClassInfo(value = "标注在类上",className = "-->com.hanpang.java.AnnotationExample") public class AnnotationExample { //新增代码 @FieldInfo(value = "方位为属性和字段",desc = "不测试了,累挺!!") public String account = null; public static void main(String[] args) { } @Override @MethodInfo(author = "wukong", comments = "Main method", date = "2016-04-27", revision = 1) public String toString() { return "Overriden toString method"; } @Deprecated @MethodInfo(comments = "deprecated method", date = "2016-04-27") public static void oldMethod(@ParameterInfo(value = "刘文铭",desc = "测试参数注解解析") String user_name) { System.out.println("old method, don't use it."+user_name); } @SuppressWarnings({ "unchecked", "deprecation" }) @MethodInfo(author = "bajie", comments = "Main method", date = "2016-04-27", revision = 10) public static void genericsTest() throws FileNotFoundException { List l = new ArrayList(); l.add("abc"); oldMethod("悟空"); } } |
package com.hanpang.java; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Method; public class AnnotationParsing { public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException { //1.获取类 Class clz = AnnotationExample.class; //2.获取属性对象 Field field = clz.getField("account");//clz.getDeclaredField() 没有测试 //3.获取注解数组 Annotation[] annotations = field.getAnnotations(); for (Annotation annotation : annotations) { if(annotation instanceof FieldInfo){ FieldInfo fi = (FieldInfo)annotation; System.out.println("-->>hanpang<<--fi.value()值=" + fi.value() + "," + "当前类=AnnotationParsing.main()"); System.out.println("-->>hanpang<<--fi.desc()值=" + fi.desc() + "," + "当前类=AnnotationParsing.main()"); } } } } |
运行结果: -->>hanpang<<--fi.value()值=方位为属性和字段,当前类=AnnotationParsing.main() -->>hanpang<<--fi.desc()值=不测试了,累挺!!,当前类=AnnotationParsing.main() |
package com.hanpang.java; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Method; public class AnnotationParsing { public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException { //1.获取类 Class clz = AnnotationExample.class; //2.获取属性 注意一定是public的,如果set方法需要单独进行处理 Field field = clz.getField("account");//clz.getDeclaredField() 没有测试 //3.获取注解数组 Annotation annotation = field.getAnnotation(FieldInfo.class); if(annotation instanceof FieldInfo){ FieldInfo fi = (FieldInfo)annotation; System.out.println("-->>hanpang<<--fi.value()值=" + fi.value() + "," + "当前类=AnnotationParsing.main()"); System.out.println("-->>hanpang<<--fi.desc()值=" + fi.desc() + "," + "当前类=AnnotationParsing.main()"); } } } |
高级篇 KZ002.反射读取注解[未封装]的更多相关文章
- javaSE高级篇4 — 反射机制( 含类加载器 ) — 更新完毕
反射机制 1.反射机制是什么?----英文单词是:reflect.在java.lang包下---这才是java最牛逼的技术 首先提前知道一句话----在java中,有了对象,于是有了类,那么有了类之后 ...
- javaSE高级篇6 — 注解( 附:注解底层解析 ) —— 更新完毕
注解 ---- 英文:annotation 1.注解长什么样子? @xxxxxxx( 一些信息 ) ----- 这个信息可有可无 2.注解可以放在什么地方? 类本身的上面.属性的上面.方法的上面.参数 ...
- JAVA高级特性反射和注解
反射: 枚举反射泛型注解.html34.3 KB 反射, 主要是指通过类加载, 动态的访问, 检测和修改类本身状态或行为的一种能力, 并能根据自身行为的状态和结果, 调整或修改应用所描述行为的状态和相 ...
- Java高级特性——反射机制(完结)——反射与注解
按照我们的学习进度,在前边我们讲过什么是注解以及注解如何定义,如果忘了,可以先回顾一下https://www.cnblogs.com/hgqin/p/13462051.html. 在学习反射和注解前, ...
- Java高级篇(四)——反射
之前写到了设计模式的代理模式,因为下一篇动态代理等内容需要用到反射的知识,所以在之前Java篇的基础上再写一篇有关反射的内容,还是以实际的程序为主,了解反射是做什么的.应该怎么用. 一.什么是反射 反 ...
- ORM查询语言(OQL)简介--高级篇:脱胎换骨
相关文章内容索引: ORM查询语言(OQL)简介--概念篇 ORM查询语言(OQL)简介--实例篇 ORM查询语言(OQL)简介--高级篇:脱胎换骨 ORM查询语言(OQL)简介--高级篇(续):庐山 ...
- ORM查询语言(OQL)简介高级篇
ORM查询语言(OQL)简介--高级篇:脱胎换骨 在写本文之前,一直在想文章的标题应怎么取.在写了<ORM查询语言(OQL)简介--概念篇>.<ORM查询语言(OQL)简介--实例篇 ...
- 【转】JAVA反射与注解
转载自:https://www.daidingkang.cc/2017/07/18/java-reflection-annotations/ 前言 现在在我们构建自己或公司的项目中,或多或少都会依赖几 ...
- 面试题_Spring高级篇
Spring高级篇 1.什么是 Spring 框架? Spring 框架有哪些主要模块? Spring 框架是一个为 Java 应用程序的开发提供了综合.广泛的基础性支持的 Java 平台. Spr ...
随机推荐
- OLEDB 命令转换组件的用法
在数据流任务组件中,OLEDB 命令转换组件对输入的每行数据调用TSQL,该组件能够把输入的数据作为参数,因此,该转换组件主要用于运行参数化的查询. 命令转换组件的配置十分简单,只有三个可编辑属性,位 ...
- JavaScript快速入门-简介
一.JavaScript历史(摘自w3school) JavaScript 是因特网上最流行的脚本语言,它存在于全世界所有 Web 浏览器中,能够增强用户与 Web 站点和 Web 应用程序之间的交互 ...
- 如何有效的报告bug?
对于比较棘手的bug,反馈务须清晰.详细.精确,我们给出以下6个建议: 1.现场演示:重复bug出现的操作步骤.这个适用于公司内部人员. 2.详细描述:在什么系统使用哪个版本的YoMail,做了什 ...
- ECC检验与纠错
引入ECC ECC:Error Checking and Correction,是一种差错检测和修正的算法. NAND闪存在生产和使用中都会有坏块产生,BBM就是坏块的管理机制.而生产坏块已经无法避免 ...
- C#_IO操作
1.创建文件夹 //using System.IO; Directory.CreateDirectory(%%1); 2.创建文件 //using System.IO; File.Create(% ...
- CentOS 6.8 安装Maven
1.下载maven安装包到developer文件目录下 2,解压缩maven,命令: -bin.tar.gz 3.配置maven路径到环境变量中 export JAVA_HOME=/usr/java/ ...
- idou老师教你学Istio 17 : 通过HTTPS进行双向TLS传输
众所周知,HTTPS是用来解决 HTTP 明文协议的缺陷,在 HTTP 的基础上加入 SSL/TLS 协议,依靠 SSL 证书来验证服务器的身份,为客户端和服务器端之间建立“SSL”通道,确保数据运输 ...
- Shell 基础 -- 流编辑器 sed 详解
一.流编辑器 sed 与命令 sed Linux 中,常使用流编辑器 sed 进行文本替换工作.与常使用的交互式编辑器(如vim)不同,sed 编辑器以批处理的方式来编辑文件,这比交互式编辑器快得多, ...
- Codeforces Round #550 (Div. 3) E. Median String (模拟)
Median String time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- 第二阶段Sprint10
昨天:查看有关“共享平台”的资料,看如何实现上传下载功能,并尝试编码,没有成功 今天:集合三个人的代码,整合到一起,修复出现的Bug 遇到的问题:看Bug没有出现,但功能不是停止运行就是部分不能用,只 ...