1.概述 是什麼:是對方法、類、參數、包、域以及變數等進行代碼功能的增強或者修改程式的行為等操作。 應用 跟蹤代碼依賴性,實現替代配置文件功能在反射中使用Annotation,欄位格式化(如:數據欄位脫敏、日期格式)在編譯時進行格式檢查生成幫助文檔 2.註解相關知識 元註解指的是所有註解都基於它們而 ...
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}
註解值成功傳入到實例化對象中的對應欄位,並返回實例化對象給調用者。
原創不易,三聯支持:點贊、在看、分享