• Java-注解基础


    注解

    1. 注解语法

    1.1 注解接口

    modifiers @interface AnnotationName{
        elementDeclaration1;
        elementDeclaration2;
        ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    每个元素声明都有如下形式:

    type elementName();
    
    • 1

    或者:

    type elementName() default value;
    
    • 1

    所有注解接口都隐式地扩展自 java.lang.annotation.Annotation接口。这是个常规接口,不是一个注解接口。

    注解元素的类型为下列之一:

    • 基本类型(int, short, long, byte, char, double, float 或者 double)
    • String
    • Class (具有一个可选的类型参数,例如 Class
    • enum枚举类型
    • 注解类型
    • 上述所述类型组成的数组

    合法例子:

    public @interface Example{
        enum Status {A, B, C, D};
        boolean isOK() default false;
        String assignedTo() default "[none]";
        Class<?> test() default Void.class;
        Status status() default Status.A;
        Reference ref() default @Reference();//这是一个注解类型
        String[] report();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    1.2 常用方法

    • Class<? extends Annotation> annotationType();
      
      • 1

      返回Class对象,用于描述该注解对象的注解接口。注意:调用注解对象上的getClass()方法可以返回真正的类,而不是返回接口。

    • boolean equals(Object other);
      
      • 1

      判断other是否实现了同样的注解接口,并且该对象与other的所有元素都彼此相等。

    • int hashCode()
      
      • 1
    • String toString()
      
      • 1

      返回一个包含注解接口名以及元素值的字符串表示。例如 @Example(assignedTo=[none],isOk=false)

    1.3 注解(打上注解)

    每个注解都具有下面这种格式:

    @AnnotationName(elementName1 = value1, elementName2 = value2, ...)
    
    • 1

    元素的顺序无关紧要。如果某个元素没有指定,将会使用声明的默认值。

    简化注解:

    • 标记注解:没有指定元素,不需要圆括号:

      @AnnotationName
      
      • 1
    • 单值注解:只有唯一元素,且该元素具有特定的名字 value,则可以忽略元素名以及等号:

      @AnnotationName("someValue")
      
      • 1
    • 所有注解都是由编译器计算而来的,因此所有元素值必须是编译器常量。

    • 一个项可以有多个注解

    • 注解可以重复声明

    • 注解元素不能设置为 null

    • 不允许循环依赖,例如:在注解A中有一个注解类型为B的注解元素,则B中不能再拥有一个类型为A的注解元素。

    1.4 注解的声明

    注解可以出现的声明处:

    • 类(包括enum)
    • 接口(包括注解接口)
    • 方法
    • 构造器
    • 实例域(包括enum常量)
    • 局部变量
    • 参数变量
    • 类型参数

    对于类和接口,声明如下:

    @Entity
    public class User{...}
    
    • 1
    • 2

    对于变量,声明如下:

    @SuppressWarnings("unchecked")
    List<User> users = ...;
    
    public User getUser(@Param("id") String userId)
    
    • 1
    • 2
    • 3
    • 4

    泛化类或者方法中的类型参数,声明可以如下:

    public class Cache<@Immutable V>{...}
    
    • 1

    1.5 注解类型的用法

    类型用法注解可以出现在下面的位置:

    @NonNull注解可以通过静态分析工具检查参数不为空的断言是否有效

    • 与泛型类型引元一起使用:

      List<@NonNull String>,
      Comparator.<@NonNull String>reverseOrder() //这是静态泛型方法的调用方式
      
      • 1
      • 2
    • 在数组中的任何位置:

      @NonNull String[][] words,//表示words[i][j]不为null
      String @NonNull[][] words,//表示words不为null
      String[] @NonNull[] words //表示words[i]不为null
      
      • 1
      • 2
      • 3
    • 与超类和实现接口一起使用:

      class Warning extends @Localized Message
      
      • 1
    • 与构造器一起使用:

      new @Localized String(...)
      
      • 1
    • 与强制转型和instanceof检查一起使用:

      (@Localized String)text,
      if(text instanceof @Localized String)
      
      • 1
      • 2

      这些注解只提供给外部工具使用,对代码实际逻辑没有任何影响

    • 与异常规约一起使用:

      public String read() throws @Localized IOException;
      
      • 1
    • 与通配符和类型边界一起使用:

      List<@Localized ? extends Message>,
      List<? extends @Localized Message>
      
      • 1
      • 2

    2. 标准注解

    2.1 一些常见的注解

    • @Override

      应用场合:方法

      目的:检查该方法是否覆盖了某一个父类方法

    • @Resource

      应用场合:类、接口、方法、域

      目的:在类或者接口上时,标记为在其他地方要用到的资源;在方法或域上时,为“注入”而标记。

    • @Target

      应用场合:注解

      目的:限制该注解可以应用到哪些项。

      例子:

      @Target({ElementType.TYPE, ElementType.METHOD})
      public @interface AnnotationName
      
      • 1
      • 2
    • @Retention

      应用场合:注解

      目的:指明这个注解可以保留多久,或者说指明这个注解的生命周期

      例子:

      @Retention(RetentionPolicy.RUNTIME)
      public @interface ActionListener
      
      • 1
      • 2
    • @Inherited

      应用场合:类的注解

      目的:指明当这个注解应用于一个类的时候,能够自动被它的子类继承。

    3. 自定义注解

    使用@interface自定义注解时候,自动继承了 java.lang.annotation.Annotation接口

    • @interface用来声明一个注解,格式:public @interface AnnotationName{...}

    • 其中的每一个方法实际上是声明了一个配置参数,如下的value虽然看着像是方法,其实是一个叫做value的配置参数

      @interface Example{
          String value() default "[none]"
      }
      
      • 1
      • 2
      • 3
    • 方法的名称就是参数的名称

    • 返回值类型就是参数的类型(只能是基本类型,Class,String,enum)

    • 可以通过default声明参数的默认值。如果没有默认值,使用时必须要赋值。

    • 如果只有一个参数成员,一般设置参数名为value,成为单值注解

    • 注解元素必须要有值,不允许为null,可以使用0、空字符串。

    • 注解元素之间没有顺序性。

    自定义一个简单注解,例子:

    @Target({ElementType.TYPE, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @interface MyAnnotation{
        String name() default "";
        int id() default -1;
        int age() default 0;
        String[] studentIds() default {"U1101","U1102"};
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    4. 使用反射操作注解

    核心方法:

    //返回类,方法或者域上的具体某个注解
    field.getAnnotation(Class<?> annotationType);
    method.getAnnotation(Class<?> annotationType);
    cl.getAnnotation(Class<?> annotationType);
    
    obj.getAnnotations();//返回类,方法或者域上的所有注解
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    场景:类与数据库的关联。

    首先看一下学生类:

    class Student{
        privateint id;
        private int age;
        private String name;
        
        public Student(){  
        }
        
        public Student(int id,int age, String name){
            this.id = id;
            this.age= age;
            this.name = name;
        }
        //getter setter
        ...
        //toString
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    创建一个类名的注解:

    @Target({ElementType.TYPE})//要作用在类上
    @Retention(RetentionPolicy.RUNTIME)//运行时
    @interface Table{
        String value();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    将Table注解作用在Student类上:

    @Table("db_name")
    public Student{...}
    
    • 1
    • 2

    创建一个属性的注解:

    @Target({ElementType.FIELD})//要作用在域上
    @Retention(RetentionPolicy.RUNTIME)//运行时
    @interface FieldAnnotation{
        String columnName();//数据库中的列名
        String type();//数据库中的类型
        int length();//长度
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    作用在学生类中的各个要与数据库关联的域上:

    public class Student{
        @FieldAnnotation(columnName = "db_id", type = "int", length = 10)
        private int id;
        @FieldAnnotation(columnName = "db_age", type = "int", length = 10)
        private int age;
        @FieldAnnotation(columnName = "db_name", type = "varchar", length = 3)
        private String name;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    最后,通过反射来进行关联:

    public static void main(String[] args) throws Exceptions{
        Class cl = Class.forName("com.example.Student");
        //通过反射获取注解
        Annotation[] annotations = cl.getAnnotations();//获取所有注解
        //获取注解的value的值
        //首先获取该类中为Table.class的注解
       Table tableAnnotation = (Table) cl.getAnnotation(Table.class);
        //然后获取该注解中的值
        String value = tableAnnotation.value();
        
        //获取域的注解
        //首先通过反射获取域
        Field f = cl.getDeclaredField("name");
        //在通过域,获取加在域上的注解
        FieldAnnotation fieldAnnotation = (FieldAnnotation)f.getAnnotation(FieldAnnotation.class);
        //获取name域上打上的注解的值
        String columnName = fieldAnnotation.columnName();
        String type = fieldAnnotation.type();
        int length = fieldAnnotation.length();
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    我们获取到所有注解上的参数后,就可以拼接出数据库需要的语句,完成我们的目的。

  • 相关阅读:
    字节3-1级别神人把《数据结构与算法》完美讲透了,带源码笔记
    人工神经网络算法的应用,人工神经网络算法步骤
    从 Delta 2.0 开始聊聊我们需要怎样的数据湖
    支付宝"手机网站支付"主域名申请了,二级域名还要申请吗
    C语言动态规划解决0-1背包问题
    TCP协议之《预分配缓存额度sk_forward_alloc--TCP接收》
    IC Compiler指南——布图规划(一)
    java_jsp-ssm留学申请服务系统springmvc
    〖全域运营实战白宝书 - 运营角色认知篇①〗- 初识运营,明晰运营的学习路径
    华为数通方向HCIP-DataCom H12-831题库(多选题:101-120)
  • 原文地址:https://blog.csdn.net/weixin_43093006/article/details/128020301