1. 程式人生 > >【Java基礎】註解(Annotation)

【Java基礎】註解(Annotation)

 

  • 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