• 高级篇 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();

    }

      

    • 注解方法不能有参数
    • 注解方法的返回类型局限于原始类型,字符串,枚举,注解,或以上类型构成的数组
    • 注解方法可以包含默认值
    • 注解可以包含与其绑定的元注解,元注解为注解提供信息,有四种元注解类型:
      • @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()");

    }

    }

    }

      

       

  • 相关阅读:
    jmeter(六)元件的作用域与执行顺序
    通过数据自动生成流程图(前端方向) dagred3
    jmeter(二)录制脚本
    最准的中文文本相似度计算工具
    BERT文本相似度实战
    Jmeter 字符串拼接参数
    常见数据库字段类型与java.sql.Types的对应
    jmeter(二十七)分布式压测注意事项
    词法分析利用Jieba实现高频词提取(Python)
    jmeter(二十一)jmeter常用插件介绍
  • 原文地址:https://www.cnblogs.com/pangxiansheng/p/5445000.html
Copyright © 2020-2023  润新知