java-注解

使用注解

注解(Annotation)是放在Java源码的类、方法、字段、参数前的一种标签。
注解本身对代码逻辑没有任何影响,如何使用注解由工具决定。

编译器可以使用的注解:

  • @Override 让编译器检查该方法是否正确实现了覆写

  • @Deprecated 告诉编译器,该方法被标记为“作废”,在其他地方引用将会出现警告

  • @SuppressWarnings 告诉编译器,在这个方法内部如果出现警告,编译器会忽略这些编译警告。

    public class Hello {

    @Override
    public String toString() {
    return "Hello";
    }
    @Deprecated
    public void hello(String name) {
    System.out.println("name");
    }
    @SuppressWarnings("unused")
    public void hello() {
    int n; //local variable n is not used
    }

    }

注解可以定义配置参数和默认值。

  • 配置参数由注解类型定义

  • 配置参数可以包括:

    • 所有的基本类型

    • String

    • 枚举

    • 数组

  • 配置参数必须是常量

    public class Hello {

    int n=100;

    @Test(timeout=100)
    public void test() {
    System.out.println("Test");
    }
    }

  • 缺少某个配置参数将使用默认值

  • 如果只写常量相当于省略了value参数

  • 如果只写注解相当于全部使用默认

    public class Hello {
    @Check(min=0,max=100,value=50)
    public int n;

    @Check(value=99)
    public int p;

    @Check(99) ///@Check(value=99)
    public int x;

    @Check
    public int y;
    }


定义注解

使用@interface定义注解(Annotation)

  • 注解的参数类似无参方法

  • 可以设定一个默认值(推荐)

  • 把最常用的参数值命名为value(推荐)

    public @interface Report {
    int type() default 0;
    String level() default "info";
    String value() default "";
    }

使用元注解定义注解:

  • @Target定义Annotation 可以被应用于源码的那些位置:

    • 类和接口 :ElementType.TYPE

    • 字段:ElementType.FIELD

    • 方法:ElementType.METHOD

    • 构造方法:ElementType.CONSTRUCTOR

    • 方法参数:ElementType.PARAMETER

      @Target(ElementType.METHOD)
      public @interface Report {
      int type() default 0;
      String level() default "info";
      String value() default "";
      }

  • @Retention定义Annotation的生命周期

    • 仅编译期:RetentionPolicy.SOURCE

    • 仅class文件:RetentionPolicy.CLASS

    • 运行期:RetentionPolicy.RUNTIME

    • 如果@Retention不存在,则该Annotation默认为CLASS

    • 通常自定义的Annotation都是RUNTIME

      @Retention(RetentionPolicy.RUNTIME)
      public @interface Report {
      int type() default 0;
      String level() default "info";
      String value() default "";
      }

  • @Repeatable定义 Annotation是否可重复

    • JDK > 1.8
  • @Inherited定义子类是否可以继承父类的Annotation

    • 仅针对@Target为Type类型的Annotation
    • 仅针对class的继承
    • 对interface的继承无效

定义Annotation的步骤:

  1. @interface定义注解

  2. 用元注解(meta annotation)配置注解
    Target:必须设置
    Retention:一般设置为RUNTIME
    通常不必写@Inherited, @Repeatable等等

  3. 定义注解参数和默认值


处理注解

使用反射API读取Annotation:

  • Class.isAnnotationPresent(Class)

  • Field.isAnnotationPresent(Class)

  • Method.isAnnotationPresent(Class)

  • Constructor.isAnnotationPresent(Class)

    Class cls = Person.class;
    //判断@Report是否存在
    cls.isAnnotationPresent(Report.class);

  • Class.getAnnotation(Class)

  • Field.getAnnotation(Class)

  • Method.getAnnotation(Class)

  • Constructor.getAnnotation(Class)

    Class cls = Person.class;
    cls.isAnnotationPresent(Report.class);
    Report report = cls.getAnnotation(Report.class);
    //如果不存在返回null
    int type = report.type();
    String level = report.level();

  • getParameterAnnotations() //返回一个二位数组

可以通过工具处理注解来实现相应的功能:

  • 对JavaBean的属性值按规则进行检查

  • JUnit会自动运行@Test标记的测试方法

posted @ 2019-09-08 14:56  马小八  阅读(248)  评论(0)    收藏  举报