创建自定义注解

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();

}

  • 注解方法不能有参数
  • 注解方法的返回类型局限于原始类型,字符串,枚举,注解,或以上类型构成的数组
  • 注解方法可以包含默认值。
  • 注解可以包含与其绑定的元注解,元注解为注解提供信息,有四种元注解类型:
    • @Documented – 表示使用该注解的元素应被javadoc或类似工具文档化,它应用于类型声明,类型声明的注解会影响客户端对注解元素的使用。如果一个类型声明添加了Documented注解,那么它的注解会成为被注解元素的公共API的一部分。
    • @Target – 表示支持注解的程序元素的种类,一些可能的值有TYPE, METHOD, CONSTRUCTOR, FIELD等等。如果Target元注解不存在,那么该注解就可以使用在任何程序元素之上
    • @Inherited – 表示一个注解类型会被自动继承,如果用户在类声明的时候查询注解类型,同时类声明中也没有这个类型的注解,那么注解类型会自动查询该类的父类,这个过程将会不停地重复,直到该类型的注解被找到为止,或是到达类结构的顶层(Object)。
    • @Retention – 表示注解类型保留时间的长短,它接收RetentionPolicy参数,可能的值有SOURCE, CLASS, 以及RUNTIME

复习一下:

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<<--value值=标注在类上,当前类=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<<--author值=wukong,当前类=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();

}

//加大加粗为新增代码部分
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(@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.反射读取注解[未封装]的更多相关文章

  1. javaSE高级篇4 — 反射机制( 含类加载器 ) — 更新完毕

    反射机制 1.反射机制是什么?----英文单词是:reflect.在java.lang包下---这才是java最牛逼的技术 首先提前知道一句话----在java中,有了对象,于是有了类,那么有了类之后 ...

  2. javaSE高级篇6 — 注解( 附:注解底层解析 ) —— 更新完毕

    注解 ---- 英文:annotation 1.注解长什么样子? @xxxxxxx( 一些信息 ) ----- 这个信息可有可无 2.注解可以放在什么地方? 类本身的上面.属性的上面.方法的上面.参数 ...

  3. JAVA高级特性反射和注解

    反射: 枚举反射泛型注解.html34.3 KB 反射, 主要是指通过类加载, 动态的访问, 检测和修改类本身状态或行为的一种能力, 并能根据自身行为的状态和结果, 调整或修改应用所描述行为的状态和相 ...

  4. Java高级特性——反射机制(完结)——反射与注解

    按照我们的学习进度,在前边我们讲过什么是注解以及注解如何定义,如果忘了,可以先回顾一下https://www.cnblogs.com/hgqin/p/13462051.html. 在学习反射和注解前, ...

  5. Java高级篇(四)——反射

    之前写到了设计模式的代理模式,因为下一篇动态代理等内容需要用到反射的知识,所以在之前Java篇的基础上再写一篇有关反射的内容,还是以实际的程序为主,了解反射是做什么的.应该怎么用. 一.什么是反射 反 ...

  6. ORM查询语言(OQL)简介--高级篇:脱胎换骨

    相关文章内容索引: ORM查询语言(OQL)简介--概念篇 ORM查询语言(OQL)简介--实例篇 ORM查询语言(OQL)简介--高级篇:脱胎换骨 ORM查询语言(OQL)简介--高级篇(续):庐山 ...

  7. ORM查询语言(OQL)简介高级篇

    ORM查询语言(OQL)简介--高级篇:脱胎换骨 在写本文之前,一直在想文章的标题应怎么取.在写了<ORM查询语言(OQL)简介--概念篇>.<ORM查询语言(OQL)简介--实例篇 ...

  8. 【转】JAVA反射与注解

    转载自:https://www.daidingkang.cc/2017/07/18/java-reflection-annotations/ 前言 现在在我们构建自己或公司的项目中,或多或少都会依赖几 ...

  9. 面试题_Spring高级篇

    Spring高级篇 1.什么是 Spring 框架? Spring 框架有哪些主要模块?  Spring 框架是一个为 Java 应用程序的开发提供了综合.广泛的基础性支持的 Java 平台. Spr ...

随机推荐

  1. libgdx学习记录10——Particle粒子

    粒子对制作画面特效很有用,可以使用Particle Editor进行自行编辑粒子效果,跟图片一起生成.p粒子文件,然后导入到程序中使用. 本文所用的粒子效果是基于其自带的demo的. 实例: pack ...

  2. java算法面试题

    前言:线上面试题与大家分享,并记录求职道路的酸甜苦辣,特此留念. 李雷和韩梅梅坐前后排,上课想说话怕被老师发现,所以改为传小纸条.为了不被老师发现他们纸条上说的是啥,他们约定了如下方法传递信息:将26 ...

  3. PAT甲题题解-1108. Finding Average (20)-字符串处理

    求给出数的平均数,当然有些是不符合格式的,要输出该数不是合法的. 这里我写了函数来判断是否符合题目要求的数字,有点麻烦. #include <iostream> #include < ...

  4. LINUX内核分析第二周学习总结——操作系统是如何工作的

    LINUX内核分析第二周学习总结——操作系统是如何工作的 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course ...

  5. javascript 数组对象及其方法

    数组声明:通过let arr = new Array(); 或者 let arr = []; 数组对象可调用的方法: 1)find方法,使用情况是对数组进行筛选遍历,find方法要求某个函数(A)作为 ...

  6. 第四篇——Spring音乐登录界面设计及实现(C#)

    Spring音乐播放器,我们小组设计其启动时有一个登录界面,用户初次可以注册,输入用户名和密码,点击注册即将输入信息保存到register文本文件中:如果已有用户名,输入用户名和密码,点击登录,程序会 ...

  7. ElasticSearch 2 (24) - 语言处理系列之停用词:性能与精度

    ElasticSearch 2 (24) - 语言处理系列之停用词:性能与精度 摘要 在信息检索早期,磁盘和内存相较我们今天的使用只是很小的一部分.将索引空间保持在一个较小的水平是至关重要的,节省每个 ...

  8. Android TextView中图文混排设置行间距导致高度不一致问题解决

    最近项目中需要实现一个评论带表情的功能,刚开始一切顺利,非常easy,突然有一天发现文字跟表情混排的时候,TextView中图文高度不一致,excuse...什么鬼,之前明明测试过图文混排,不存在这个 ...

  9. HTML5之HTTP协议

    ---恢复内容开始--- 99%的人都理解错了HTTP中GET与POST的区别 2016.10.11 13:23:22来源: 51cto作者:51cto   (转)   GET和POST是HTTP请求 ...

  10. week5-Internetwork Layer

    Technology:Internets and Packets course Layer 2 : Internet Protocol The InterNetwork Internetwork La ...