1. 程式人生 > 其它 >Java註解--一張圖一案例掌握自定義註解

Java註解--一張圖一案例掌握自定義註解

1.概述

是什麼:是對方法、類、引數、包、域以及變數等進行程式碼功能的增強或者修改程式的行為等操作。

應用

  • 跟蹤程式碼依賴性,實現替代配置檔案功能
  • 在反射中使用Annotation,欄位格式化(如:資料欄位脫敏、日期格式)
  • 在編譯時進行格式檢查
  • 生成幫助文件

2.註解相關知識

元註解指的是所有註解都基於它們而產生的最基礎的註解。

2.1.Annotation介面和元註解

這張圖包含了Annotation介面資訊、4個元註解作用和元註解的引數資訊

整體關係(具體資訊都在圖中)

  • 頂級註解介面:Annotation

  • 元註解

    • @Documented
    • @Inherited
    • @Target
    • @Retention
  • native級別的關鍵字

    • @interface 指明是註解類

關聯關係

  • 1個Annotation 和 1個RetentionPolicy關聯。

    • 可以理解為:每1個Annotation物件,都會有唯一的RetentionPolicy屬性。
  • 1個Annotation 和 1~n個ElementType關聯。

    • 可以理解為:對於每1個Annotation物件,可以有若干個ElementType屬性。

2.2.註解元素支援的資料型別

  • 所有基本型別
  • String
  • Class
  • enum
  • annotation
  • 以上型別的陣列

2.3.常見基礎註解的作用

@SuppressWarnings:抑制編譯器警告的註解,編譯檢查註解

@Deprecated:棄用註解,編譯檢查註解

@Override:限定重寫父類方法的註解,具有編譯檢查作用

@FunctionalInterface:函式式介面註解,限制介面只能有一個抽象方法

3.自定義註解

返回值型別等於引數的型別,

方法的名稱等於引數的名稱(使用註解是引數名稱),

可以通過default關鍵字來宣告引數的預設值。

通過一個案例來理解註解的使用(不懂反射的可以看我的另一篇文章)

3.1.案例:通過反射處理自定義註解

自定義註解類:顏色註解類 + 顏色列舉

@Target( ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ColorBanana {
    /**
     * 顏色列舉類
     */
    public enum Color{
        YELLOW,
        BLACK,
        WHITE,
        RED
    }
    // 顏色屬性
    Color colorBanana() default Color.YELLOW;

}

實體類:使用註解的類

public class Banana {

    private String bananaName;
    @ColorBanana(colorBanana = ColorBanana.Color.RED)
    private String bananaColor;

    public String getBananaName() {
        return bananaName;
    }

    public void setBananaName(String bananaName) {
        this.bananaName = bananaName;
    }

    public String getBananaColor() {
        return bananaColor;
    }

    public void setBananaColor(String bananaColor) {
        this.bananaColor = bananaColor;
    }
    @Override
    public String toString() {
        return "Banana{" + "bananaName=" + bananaName + ", bananaColor=" + bananaColor + "}";
    }
}

測試類:反射處理註解

public class BananaTest {

    // 建立註解賦值後的Banana例項物件
    public static Banana newBanana() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class<Banana> bananaClass = Banana.class;
        Banana banana = bananaClass.getConstructor().newInstance();
        /**
         * 獲取Banana類中 ColorBanana註解資訊
         *   因為註解資訊打在成員變數上,所以要通過Filed來get註解
         *   (註解打在什麼上,就用什麼來獲取註解)
         */
        Field[] fields = bananaClass.getDeclaredFields();//註解打在私有成員變數,所以要用getDeclaredFields
        for (Field field : fields){
            field.setAccessible(true);//忽略私有修飾符得限制,否則報語法錯誤
            // 拿到註解
            ColorBanana annotation = field.getAnnotation(ColorBanana.class);
            // 有些欄位沒有ColorBanana註解,記得判空
            if (annotation != null){
                ColorBanana.Color color = annotation.colorBanana();
                System.out.println("輸出註解中得資訊:"+field.getName()+"="+color);
                /*
                 * 將註解中得資訊賦值到物件對應欄位中
                 *   因為實體類Banana 的bananaColor欄位是字串,所以要拿列舉類屬性得name(名稱)進行賦值
                 */
                field.set(banana,color.name());
            }
        }
        // 輸出反射得到得物件資訊
        System.out.println(banana);
        return banana;
    }

    public static void main(String[] args) throws Exception {
        Banana banana = newBanana();
        banana.setBananaName("myBananaName");
        System.out.println(banana);
    }
}

執行結果:

輸出註解中得資訊:bananaColor=RED

Banana{bananaName=null, bananaColor=RED}

Banana{bananaName=myBananaName, bananaColor=RED}

註解值成功傳入到例項化物件中的對應欄位,並返回例項化物件給呼叫者。

Java往期文章

Java全棧學習路線、學習資源和麵試題一條龍

我心裡優秀架構師是怎樣的?

免費下載經典程式設計書籍

原創不易,三聯支援:點贊、在看、分享