• Java实现自定义注解开发


    Java实现自定义注解开发

     

    一直都对注解开发挺好奇的,最近终于有时间自己实践了一把,记录一下 万一后期会用到呢 哈哈哈 

    首先我们了解一下自定义注解的标准示例,注解类使用 @interface 关键字修饰,且在注解类上方声明注解相关信息,包含以下四种信息

    @Documented – 注解是否将包含在JavaDoc中
    
    @Retention – 什么时候使用该注解
    
    @Target – 注解用于什么地方
    
    @Inherited – 是否允许子类继承该注解
    

      

     1.)@Retention – 定义该注解的生命周期

    ●   RetentionPolicy.SOURCE : 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
    ●   RetentionPolicy.CLASS : 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式
    ●   RetentionPolicy.RUNTIME : 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。

      2.)Target – 表示该注解用于什么地方。默认值为任何元素,表示该注解用于什么地方。可用的ElementType 参数包括

     ● ElementType.CONSTRUCTOR: 用于描述构造器
     ● ElementType.FIELD: 成员变量、对象、属性(包括enum实例)
     ● ElementType.LOCAL_VARIABLE: 用于描述局部变量
     ● ElementType.METHOD: 用于描述方法
     ● ElementType.PACKAGE: 用于描述包
     ● ElementType.PARAMETER: 用于描述参数
     ● ElementType.TYPE: 用于描述类、接口(包括注解类型) 或enum声明

     3.)@Documented – 一个简单的Annotations 标记注解,表示是否将注解信息添加在java 文档中。

     4.)@Inherited – 定义该注释和子类的关系
      @Inherited 元注解是一个标记注解,@Inherited 阐述了某个被标注的类型是被继承的。

      如果一个使用了@Inherited 修饰的annotation 类型被用于一个class,则这个annotation 将被用于该class 的子类。

     

    自定义注解类的声明

    @Target(value= {ElementType.TYPE,ElementType.METHOD,ElementType.FIELD}) 用于声明当前注解类的作用范围分别为 类 方法 属性

    @Retention(value = RetentionPolicy.RUNTIME) 运行时保留该注解,可以通过反射读取注解信息

    package com.gaunyi.batteryonline.annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * Created by S0111 on 2019/8/20.
     * 自定义注解类声明
     */
    @Target(value= {ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
    @Retention(value = RetentionPolicy.RUNTIME)
    public @interface MyAnnotationDefinition {
    
      /*定义注解里面的参数信息*/ String name(); String value(); String path(); }

     

    自定义注解使用

    分别在类、方法、属性上使用注解信息

    package com.gaunyi.batteryonline.annotation;
    
    /**
     * Created by S0111 on 2019/8/20.
     * 自定义注解类使用
     */
    @MyAnnotationDefinition(name="类名称",value="类值",path="类路径")
    public class MyAnnotationUse {
    
        @MyAnnotationDefinition(name="属性名",value="属性值",path="属性路径")
        private String name;
    
        @MyAnnotationDefinition(name="年龄",value="18",path="/user2")
        private String age;
    
        @MyAnnotationDefinition(name="方法名",value="方法值",path="方法访问路径")
        public String testAnno(){
            return "successs!!!";
        }
    
        @MyAnnotationDefinition(name="方法名1",value="方法值1",path="方法访问路径1")
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAge() {
            return age;
        }
    
        public void setAge(String age) {
            this.age = age;
        }
    }
    

    读取注解信息(测试注解类)

    这里通过反射读取注解信息,注解内容与对应的类、方法、属性对应。

    package com.gaunyi.batteryonline.annotation;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    /**
     * Created by S0111 on 2019/8/20.
     * 自定义注解类测试
     */
    public class MyAnnotationTest {
    
        public static void  main(String[] args) throws Exception{
            Class clazz = Class.forName("com.gaunyi.batteryonline.annotation.MyAnnotationUse");
    
            //获取类注解信息
            MyAnnotationDefinition classAnno =(MyAnnotationDefinition) clazz.getAnnotation(MyAnnotationDefinition.class);
            System.out.println( classAnno.name()+"---"+classAnno.value()+"---"+classAnno.path());
    
            //获取所以方法注解信息 ps:这里需要使用 isAnnotationPresent 判断方法上是否使用了注解
            Method[] allMethods = clazz.getDeclaredMethods();
            for(int i=0;i<allMethods.length;i++){
                if(allMethods[i].isAnnotationPresent(MyAnnotationDefinition.class)) {
                    MyAnnotationDefinition methodAnno = allMethods[i].getAnnotation(MyAnnotationDefinition.class);
                    System.out.println("遍历:当前方法名为:"+allMethods[i].getName()+" 的注解信息:---"+methodAnno.name() + "---" + methodAnno.value() + "---" + methodAnno.path());
                }
            }
    
            //获取指定方法注解信息
           Method methodTest = clazz.getDeclaredMethod("testAnno");
            MyAnnotationDefinition methodAnnotest =  methodTest.getAnnotation(MyAnnotationDefinition.class);
            System.out.println( methodAnnotest.name()+"---"+methodAnnotest.value()+"---"+methodAnnotest.path());
    
    
            //获取属性注解信息
            Field nameField =  clazz.getDeclaredField("name");
            MyAnnotationDefinition attrAnno = nameField.getAnnotation(MyAnnotationDefinition.class);
            System.out.println( attrAnno.name()+"---"+attrAnno.value()+"---"+attrAnno.path());
        }
    }
    

      

    测试结果

    至此我们就实现了自定义注解啦....  关于自定义注解的实际应用,待我使用时再来更新...

    关于注解的实际应用请参考此博客(通过注解标识注入相应日志信息):https://www.cnblogs.com/DFX339/p/12875544.html 

  • 相关阅读:
    字符串 CSV解析 表格 逗号分隔值 通讯录 电话簿 MD
    Context Application 使用总结 MD
    RxJava RxPermissions 动态权限 简介 原理 案例 MD
    Luban 鲁班 图片压缩 MD
    FileProvider N 7.0 升级 安装APK 选择文件 拍照 临时权限 MD
    组件化 得到 DDComponent JIMU 模块 插件 MD
    gradlew 命令行 build 调试 构建错误 Manifest merger failed MD
    protobuf Protocol Buffers 简介 案例 MD
    ORM数据库框架 SQLite 常用数据库框架比较 MD
    [工具配置]requirejs 多页面,多入口js文件打包总结
  • 原文地址:https://www.cnblogs.com/DFX339/p/11386722.html
Copyright © 2020-2023  润新知