【Java基础】注解(Annotation)

版权声明:版权所有,转载请标明链接。 https://blog.csdn.net/happyniceyq/article/details/82983562

 

  • Annotation,代码里的特殊标记,在编译、类加载、运行时被读取,并执行相应的处理。

  • 使用注解,在不改变原有逻辑的情况下,在源文件中嵌入一些补充信息。

  • Annotation提供了一种为程序元素设置元数据的方法。

  • Annotation是一个接口,通过反射来获取指定程序元素的Annotation对象,通过Annotation对象来获得注解里的元数据。

  • Annotation不能影响程序代码的执行,无论增加、删除 Annotation,代码都始终如一的执行。

一、基本Annotation

  1. 限定重写父类方法:@Override

  2. 标记已过时:@Deprecated

  3. 抑制编译器警告:@SuppressWarnings

  4. Java7的“堆污染”警告与@SafeVarargs

  5. Java8的函数式接口与@FunctionallInterface

二、JDK的元Annotation

位于java.lang.annotation包下的6个Meta Annotation(元Annotation),其中有5个元Annotation用于修饰其他的Annotation定义,@Repeatable 专门用于定义Java8新增的重复注解。

1、@Retention

@Retention用于指定被修饰的Annotation可以保留多长时间。

value成员变量的值有三个:

  1. RetentionPolicy .CLASS:编译器把注解记录在class文件中。

  2. RetentionPolicy.RUNTIME: 编译器把注解记录在class文件中,运行Java程序时,JVM获取注解信息,程序可以通过反射获取该注解信息。

  3. RetentionPolicy.SOURCE:只保留在源代码中,编译器注解丢弃。

  @Retention(RetentionPolicy.RUNTIME)
  public @interface Column {
      ...
  }

2、@Target

用于被修饰的注解能用于修饰哪些程序单元。

取值 说明
ElementType.ANNOTATION_TYPE 给一个注解进行注解
ElementType.CONSTRUCTOR 给构造方法进行注解
ElementType.FIELD 给属性进行注解
ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
ElementType.METHOD 可以给方法进行注解
ElementType.PACKAGE 可以给包进行注解
ElementType.PARAMETEP 可以给一个方法内的参数进行注解
ElementType.TYPE 可以给一个类型进行注解,比如类,接口,枚举等
  @Target(ElementType.TYPE)
  public @interface TestAnnotation {
  }
  ​

3、@Documented

用于指定被该元注解修饰的注解类将被javadoc工具提取成文档。

  @Documented
  public @interface TestAnnotation {
  }

4、@Inherited

指定被它修饰的注解将具有继承性——如果某个类使用了@Xxx注解(定义该注解时使用了@Inherited修饰)修饰,则其子类将自动被@Xxx修饰。

  @Inherited
  @Retention(RetentionPolicy.RUNTIME)
  public @interface Test {}
   
  ​
  @Test
  public class A {}
   
   
  public class B extends A {}

5、@Repeatable

Java新增的注解,允许使用多个相同类型的注解来修饰同一个类。

  @interface Persons {
      Person[]  value();
  }
   
   
  @Repeatable(Persons.class)
  @interface Person{
      String role default "";
  }
   
   
  @Person(role="artist")
  @Person(role="coder")
  @Person(role="PM")
  public class SuperMan{
   
  }

三、自定义Annotation

1、定义Annotation

定义新的Annotation类型使用@interface ,与定义一个接口类似。

  public @interface MyTag {
      //定义带两个成员变量的Annotation
      //Annotation中的成员变量以方法的形式来定义
      String name() default "yvonne";
      int age() default 25;
  }

定义Annotation之后,就可以在程序的任何地方使用该Annotation。

  public class AnnotationTest {
      @MyTag
      public void info() {
          ...
      }
  }

2、使用Annotation

  /***********注解声明***************/
  ​
  /**
   * 水果名称注解
   * @author peida
   *
   */
  @Target(ElementType.FIELD)
  @Retention(RetentionPolicy.RUNTIME)
  @Documented
  public @interface FruitName {
      String value() default "";
  }
  ​
  /**
   * 水果颜色注解
   * @author peida
   *
   */
  @Target(ElementType.FIELD)
  @Retention(RetentionPolicy.RUNTIME)
  @Documented
  public @interface FruitColor {
      /**
       * 颜色枚举
       * @author peida
       *
       */
      public enum Color{ BULE,RED,GREEN};
      
      /**
       * 颜色属性
       * @return
       */
      Color fruitColor() default Color.GREEN;
  ​
  }
  ​
  /**
   * 水果供应者注解
   * @author peida
   *
   */
  @Target(ElementType.FIELD)
  @Retention(RetentionPolicy.RUNTIME)
  @Documented
  public @interface FruitProvider {
      /**
       * 供应商编号
       * @return
       */
      public int id() default -1;
      
      /**
       * 供应商名称
       * @return
       */
      public String name() default "";
      
      /**
       * 供应商地址
       * @return
       */
      public String address() default "";
  }
  ​
  /***********注解使用***************/
  ​
  public class Apple {
      
      @FruitName("Apple")
      private String appleName;
      
      @FruitColor(fruitColor=Color.RED)
      private String appleColor;
      
      @FruitProvider(id=1,name="杨倩csdn",address="https://blog.csdn.net/happyniceyq")
      private String appleProvider;
      
      public void setAppleColor(String appleColor) {
          this.appleColor = appleColor;
      }
      public String getAppleColor() {
          return appleColor;
      }
      
      public void setAppleName(String appleName) {
          this.appleName = appleName;
      }
      public String getAppleName() {
          return appleName;
      }
      
      public void setAppleProvider(String appleProvider) {
          this.appleProvider = appleProvider;
      }
      public String getAppleProvider() {
          return appleProvider;
      }
      
      public void displayName(){
          System.out.println("水果的名字是:苹果");
      }
  }
  ​
  /***********注解处理器***************/
  ​
  public class FruitInfoUtil {
      public static void getFruitInfo(Class<?> clazz){
          
          String strFruitName=" 水果名称:";
          String strFruitColor=" 水果颜色:";
          String strFruitProvicer="供应商信息:";
          
          Field[] fields = clazz.getDeclaredFields();
          
          for(Field field :fields){
              if(field.isAnnotationPresent(FruitName.class)){
                  FruitName fruitName = (FruitName) field.getAnnotation(FruitName.class);
                  strFruitName=strFruitName+fruitName.value();
                  System.out.println(strFruitName);
              }
              else if(field.isAnnotationPresent(FruitColor.class)){
                  FruitColor fruitColor= (FruitColor) field.getAnnotation(FruitColor.class);
                  strFruitColor=strFruitColor+fruitColor.fruitColor().toString();
                  System.out.println(strFruitColor);
              }
              else if(field.isAnnotationPresent(FruitProvider.class)){
                  FruitProvider fruitProvider= (FruitProvider) field.getAnnotation(FruitProvider.class);
                  strFruitProvicer=" 供应商编号:"+fruitProvider.id()+" 供应商名称:"+fruitProvider.name()+" 供应商地址:"+fruitProvider.address();
                  System.out.println(strFruitProvicer);
              }
          }
      }
  }
  ​
  /***********输出结果***************/
  public class FruitRun {
  ​
      /**
       * @param args
       */
      public static void main(String[] args) {
          
          FruitInfoUtil.getFruitInfo(Apple.class);
          
      }
  ​
  }
  ​
  ====================================
   水果名称:Apple
   水果颜色:RED
   供应商编号:1 供应商名称:杨倩csdn 供应商地址:https://blog.csdn.net/happyniceyq

猜你喜欢

转载自blog.csdn.net/happyniceyq/article/details/82983562