• 自定义注解以及注解在反射中的应用


    ✿ 注解三要素:注解本身、被贴者、第三方程序(赋予注解的特殊功能)

    目录

     

    一、Annotation注解(也加标注)

    ■  作用在代码的注解和元注解:

    □   作用在代码的注解:

    □    元注解(作用在其他注解的注解):

    □   重点介绍一下@Retention 和 @Target:

     

    ❀ 注解重要应用:在反射中使用 Annotation

    (1)注解在类名上:

    (2)注解在方法名上:

    (3)注解在属性上:

    总结:自定义注解的使用

    ❀ 注解本质就是抽象类【把它理解成类自定义跟使用起来就so easy】

    1、定义一个注解类:

    2、使用注解(‘贴一下’)【因为定义的注解的注解范围是类,只能贴在类上】

    3、获取自定义注解标签中值,即调用自定义注解类中的方法


    一、Annotation注解(也加标注)

          Java 中的类、方法、变量、参数和包等都可以被标注。和 Javadoc 不同Java 标注可以通过反射获取标注内容(反射获取注解内容:编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容。)

    ■    注解包括:内置的注解 和 自定义注解

    其中内置的注解:Java 定义了一套注解,共有 7 个,3 个在 java.lang 中,剩下 4 个在 java.lang.annotation 中。

    ■  作用在代码的注解和元注解:

    □   作用在代码的注解:

    • @Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
    • @Deprecated - 标记过时方法。如果使用该方法,会报编译警告。
    • @SuppressWarnings - 指示编译器去忽略注解中声明的警告。

    □    元注解(作用在其他注解的注解):

    • @Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
    • @Documented - 标记这些注解是否包含在用户文档中。
    • @Target - 标记这个注解应该是哪种 Java 成员。
    • @Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)

    □   重点介绍一下@Retention 和 @Target:

    @Retention:注解的保留范围,是个枚举,有如下可选值
        RetentionPolicy.SOURCE:注解存在于源文件中
        RetentionPolicy.CLASS:注解存在于源字节码文件中
        RetentionPolicy.RUNTIME:注解存在于运行时
    
    @Target:注解出现的位置(比如类上、字段上、方法上等等),也是个枚举,有如下可选值
      ElementType.ANNOTATION _ type 应用于注释类型。
      ElementType.CONSTRUCTOR 应用于构造函数。
      ElementType.FIELD 应用于字段或属性。
      ElementType.LOCAL_VARIABLE 应用于局部变量。
      ElementType.METHOD应用于方法级注释。
      ElementType.PACKAGE 应用于包声明。
      ElementType.PARAMETER 应用于方法的参数。
      ElementType.TYPE应用于类的任何元素。

     

    ❀ 注解重要应用:在反射中使用 Annotation

    (1)注解在类名上:

    1):@注解名(“注解值”) :注解在类名上,则该类拥有了注解中信息  
         @Table(“t_student”)
         public class Student{
            ……
         }
    
     2): 然后创建注解:
    ●贴哪里:   @Target(ElementType.Type)
    ●保存时间: @Retention(RetentionPolicy.RUNTIME)
               public @interface Table {
                     String value();   //则使用@Table注解的时候: @Table(value=”t_student”);
                }    
    
     3): (该类拥有了注解中信息)使用反射获取注解信息:
         //创建注解对象:获取到Student类上的注解对象
      ① 创建注解对象       Table table = Student类.getAnnotation(Table.class);
      ② 调用注解对象的方法  String tableName =table.value();

    (2)注解在方法名上:

        1)student类中的方法test上有注解:    
        @MyAnnotation(value = "123",name = "lisi")
        public static void test(){
            ……
         }
    
        2)然后创建注解:
        ●贴哪里:  @Target(ElementType.Type)
        ●保存时间:@Retention(RetentionPolicy.RUNTIME)
                  public @interface MyAnnotation {
                        String value() default "abc";
                        String name() default "zhangsan";
                  }
    
        3)(该类的方法拥有了注解中信息)使用反射获取注解信息:
             Class clazz = Class.forName("Student的路径");
             Method[] ms = clazz.getMethods();
             for (Method m : ms) {
                if(m.isAnnotationPresent(MyAnnotation.class)){
                  //创建注解对象:获取到test方法上的注解对象;并调用注解对象的方法
                    String value = m.getAnnotation(MyAnnotation.class).value();
               String name = m.getAnnotation(MyAnnotation.class).name();
                }
            }

    (3)注解在属性上:

     1)student类中的属性id上有注解:
        @Sid(min = 6,max = 10)
         private int id;
     2)然后创建注解:
        ●贴哪里:  @Target(ElementType.Type)
        ●保存时间:@Retention(RetentionPolicy.RUNTIME)
                  public @interface Sid{
                     int min() default 1;
                     int max() default 10;
                 }
     3)(该类的属性拥有了注解中信息)使用反射获取注解信息:
           Class clazz = Class.forName("Student的路径");
           Field[] fs = clazz.getDeclaredFields();
           for (Field f: fs){
                //创建注解对象:获取属性上的@Sid注解
                Sid id = f.getAnnotation(Test.class); 
                if(id != null){
                    f.setAccessible(true);//设置属性可访问 
                  //调用注解对象的方法
                       int min = id.min();
                      int max = id.max();
                    }
            }

    总结:自定义注解的使用

    ❀ 注解本质就是抽象类【把它理解成类自定义跟使用起来就so easy】

    1、定义一个注解类:

    @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME)
     public @interface Table{
     	String value();
     } 

    ● @Target(ElementType.TYPE) 是元注解,表示自定义的注解类Table 注解的范围是TYPE 类。

    ●  @Retention(RetentionPolicy.RUNTIME) 也是元注解,表示自定义的注解类Table 注解生效是在运行RUNTIME 的时候。

    2、使用注解(‘贴一下’)【因为定义的注解的注解范围是类,只能贴在类上】

     @Table("t_stu") //本来应该写成 @Table(value="t_stu"),因为自定义注解类只有一个方法,简写
     public class Student{
     
     }
    
    
    //===============================================================================
    
    //自定义注解中有多个方法,例如一下:
    @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME)
     public @interface Table{
     	String value();
        String name();
     } 
    
    
    //贴标签
     @Table(value="fupo" name="xiaoming")  
     public class Student{
         
     }

    3、获取自定义注解标签中值,即调用自定义注解类中的方法

    ● 创建自定义注解对象,利用自定义注解对象调用方法

    //获取注解标签中的值:
    
    //(1) 先创建注解对象 
    Table table = classType.getAnnotation(Table.class);
    //【因为注解在类上】 类.getAnnotation(注解标签类))
    //【若是注解在属性】就使用: 属性.getAnnotation(注解类) 
    
    //(2)调用注解标签类中定义的方法, 获取注解标签中传递的值 
    String tableName = table.value();

  • 相关阅读:
    C++ 实现简单快速排序
    LEETCODE 198. House Robber
    leetcode 174
    GIT 版本的回退
    unorderd_map 自定义键值及哈希函数的重载
    互斥锁 形成死锁实例
    leetcode 300
    LeetCode 62
    LeetCode 122
    SVN提交,强制注释
  • 原文地址:https://www.cnblogs.com/shan333/p/15939235.html
Copyright © 2020-2023  润新知