• JAVA中自定义注解


    最近几天在学习注解相关的知识点:

    一、定义

       注解也叫作元数据,就是用来描述数据的数据。它其实就是程序代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取并执行相应的处理。注解主要是告诉编译器要做什么事情,在程序中可对任何程序元素进行注解。其可以声明在包、类。成员变量、成员方法、局部变量、方法参数等的前面,用来对这些程序元素进行说明、注释。

    二、分类

       根据注解的作用可以分为基本注解、元注解(元数据注解)与自定义注解三种。

      基本注解:在JDK8的java.lang包中,java提供了5种基本注解,可以直接在程序代码中将其当做修饰符来使用,用于所支持的程序元素,其分别是@Deprecated,@Override,@SuppressWarnings @SafeVargs @Functionallnterface

     元注解:就是对注解进行标注的注解。java中定义了6种元注解类型:@Target @Retention @Document @Inherited @Repeatable和类型注解。

    @Target用来限制注解的使用范围,即指定该注解可用于哪些程序元素

    @Retention用于说明注解的保存范围,保存范围使用枚举类型java.lang.annotation.RetentionPolicy来指定其保留策略值。

    @Document用于指定被修饰的注解可被javadoc.exe工具提取成文档。

    @Inherited用于描述一个父类的注解可以被子类继承。

    @Repeatable用于开发重复注解。

    三、自定义注解,其过程主要包括三个步骤:

    1、定义注解,使用@interface进行声明,其实就是继承了java.lang.annotation.Annotation接口.

     注解的成员由未实现的方法组成,其中的成员变量以无参数方法的形式来声明,就变量名后面必须有圆括号()

    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /*
     * 定义一个testannotation
     */
    @Target(ElementType.FIELD)//使用在成员变量上
    @Retention(RetentionPolicy.RUNTIME)//在程序执行时生效
    @Documented
    public @interface TestAnnotation {
      String description() default "";
    }

    2、解析注解,原理是利用反射来获取注解以及其对应的值

    import java.lang.reflect.Field;
    /*
     * 注解解析
     */
    public class TestAnnotationParse {
        public static String getDescription(Class<?> clazz,int key){
           Field[] fields = clazz.getDeclaredFields();
           Field f=null;
           for(Field field:fields){
               //将此对象的accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消Java语言访问检查。
          //值为 false 则指示反射的对象应该实施 Java 语言访问检查。
    
               field.setAccessible(true);
               try {
                   //判断是否存在注解,且注解的值跟入参一致
                  if(field.isAnnotationPresent(TestAnnotation.class)&&
                           Integer.valueOf(field.get(clazz).toString())==key){
                          f=field;
                          break;
                   }
            } catch (NumberFormatException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
           }
           if(f!=null)
               //获取变量上注解的值
             return f.getAnnotation(TestAnnotation.class).description();
           
           return null;
        }
        
        
        public static void main(String[] args) {
            System.out.println(TestAnnotationParse.getDescription(TestAnnotationObject.class, 200));
            System.out.println(TestAnnotationParse.getDescription(TestAnnotationObject.class, TestAnnotationObject.RET_CODE_FAIL));
        }
    }

    3、使用注解

    /*
     * 使用自定义的注解
     */
    public class TestAnnotationObject {
     @TestAnnotation(description="success")
      public static int RET_CODE_SUCC=200;
     
     @TestAnnotation(description="fail")
     public static int RET_CODE_FAIL=201;
    
    }

    在以上步骤的第二步中,需要用到反射获取注解,而且要用获取字段信息的方法来获取被注解的字段,

    这时候有个困惑,getDeclaredFields与getFields有什么区别?

    区别:

    getDeclaredFields:获得某个类的所有声明的字段,包括private 、protected、public,但是不包括父类声明的字段;

    getFields:获得某个类的所有的公共字段(public),包括父类;

    同样类似的还有

    getConstructors()和getDeclaredConstructors()、

    getMethods()和getDeclaredMethods(),

    这两者分别表示获取某个类的构造方法和成员方法。

    以上记录下来,以防忘记。

  • 相关阅读:
    HTML5+php图片自由裁剪上传功能
    一个日期时间显示框的美化风格示例
    PHP+jquery 瀑布流+LightBox图片盒子特效
    类型
    异常语句
    穷举
    练习
    累加求和
    猜拳游戏(三局两胜)
    正则表达式
  • 原文地址:https://www.cnblogs.com/sunshine2017/p/7235865.html
Copyright © 2020-2023  润新知