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  马小八  阅读(220)  评论(0编辑  收藏  举报