一篇教会你注解与自定义注解 - java

235 阅读4分钟

Java - 注解 - Annotation

前言:大家好!接下来我将带大家来学习认识一些注解和自定义注解

一、注解是什么

  • 注解(Anootation) 也被称为元数据(Metadata),用于修饰解释 包、类、方法、属性、构造器、局部变量等数据信息。
  • 和注解一样,注解不影响程序逻辑,但注解可以被编译或运行,相当于嵌入在代码中的补充信息。
  • 在JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在JavaEE中注解占据了更重要的角色,例如用来配置应用程序的如何切面,代替JavaEE旧版中所遗留的繁冗代码和XML配置等。
  • 不是程序本身,可以对程序做出解释

二、注解使用介绍

  • 使用Annotation 时要在其面前增加 @ 符号,并把该 Annotation 当成一个修饰符使用。用于修饰它支持的程序元素

  • 定义注解使用@interface 关键字

    public @interface MyAnnotation{
    }
    

三、常用注解

  • @Override : 限定某个方法,是重写父类方法,该注解只能用于方法

    • 注意,就算你不写这个注解也可以重写父类的方法
    • 你在方法上面加上这个注解,如果没有重写父类会编译错误
    • 这个注解最重要的价值就是进行语法的校验
    // Father.java
    public class Father {
        public void fly(){
            System.out.println("Father");
        }
    }
    // Son.java 
    public class Son extends Father{
        @Override
        public void fly() {
            System.out.println("Son fly...");
        }
    }
    
    
  • @Deperecated : 用于表示某个程序元素(类,方法等)已过时

    • 注意过时不等于不能使用,只是不推荐使用
    • 可以做版本升级过渡使用
  • @SupperessWarnings : 抑制编译器警告

    • 顾名思义就是不让这个类中不出现警告的下划线

    • 常用参数@SupperssWarnings({"all"})

      public class Main{
          @SupperssWarnings({"all"})
          public static void main(String[] args){}
      }
      

四、Java中的元注解

作用:用于修饰其它注解的注解叫做元注解

  • Retention : 指定注解的使用范围,三个值

    • RetentionPolicy.SOURCE : 编译器使用后,直接丢弃这种策略的注解
    • RetentionPolicy.CLASS : 编译器将这把注解记录在class文件中,当运行Java程序时,JVM 不会保留注解。这是默认值
    • RetentionPolicy.RUNTIME : 编译器将把注解记录在class文件中,当运行Java程序时,JVM 会保留注解,程序可以通过反射获取该注解
  • Target : 指定注解可以在哪些地方使用

    • 用于指定被修饰的 Annotation 能用于修饰哪些程序变量

    • TYPE:表示注解可以应用于类、接口(包括注解类型)、枚举等类型声明。

    • FIELD:表示注解可以应用于类的字段(包括枚举常量)

    • METHOD:表示注解可以应用于方法。

    • PARAMETER:表示注解可以应用于方法的参数。

    • CONSTRUCTOR:表示注解可以应用于构造函数。

    • LOCAL_VARIABLE:表示注解可以应用于局部变量。

    • ANNOTATION_TYPE:表示注解可以应用于其他注解类型(即元注解)。

    • PACKAGE:表示注解可以应用于包声明。

    • TYPE_PARAMETER:表示注解可以应用于类型参数(如泛型中的类型参数)。

    • TYPE_USE:表示注解可以应用于任何使用类型的地方(如类型转换、instanceof、泛型类型等)。

    • 例子:MyAnnotation 注解只能应用于类、接口、枚举和方法

      @Target({ElementType.TYPE, ElementType.METHOD})
      public @interface MyAnnotation {
          // 注解内容
      }
      
  • Documented : 指定该注解是否会在 javadoc 体现

    • 用于指定该元 Annotation 修饰的 Annotation 类将被 javadoc 工具提取成文档,即在生成文档时,可以看到该注解
  • Inherited : 子类会继承父类注解

    • 被当前注解修饰的注解 将具有继承性,如果某个类使用了被@Inherited 修饰的 注解 ,则其子类将自动具有该注解

五、自定义注解

  • @interface用来声明一个注解,格式:public @interface 注解名{自定义内容}

  • 其中的每一个方法实际上是声明了一个配置参数

  • 方法的名称就是参数的名称

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

  • 可以通过default来声明参数的默认值

  • 如果只有一个参数类型,一般参数名为value

  • 注解元素必须要有值,我们定义注解元素时,经常使用空字符串,0作为默认值

  • 例子:

    // 多个值的定义
    @Target({ElementType.METHOD,ElementType.FIELD,ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation {
        /**
         * 注解的参数 :参数类型  + 参数名 ();
         * 有默认值就可以不用写,
         * 没有默认值,如果不写会报错
         * @return String
         */
        String name() default "";
        int age() default 0;
        int id() default -1;// 如果默认值为 -1 ,代表不存在,indexof如果找不到就返回 -1
    }
    
    // 使用当前注解
    @MyAnnotation(name = "1",age = 0,id = 4)
    public class  Test {
    
    }
    
    // 单个值的定义
    @Target({ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation01 {
        /*
        * 如果只有一个值可以使用value来命名,在调用时可以不写value=“值”
        * */
        String value();
    }
    
    // 使用当前注解
    @MyAnnotation01("不需要键值对")
    public class  Test {
    }
    
    总结:

    注解并不难,但是很重要,后面需要配合反射一起使用才能发挥它的真正用途