你真的理解Java 注解嗎?
1、什么是注解?
官方解釋:
Java 注解用於為 Java 代碼提供元數據。作為元數據,注解不直接影響你的代碼執行,但也有一些類型的注解實際上可以用於這一目的。Java 注解是從 Java5 開始添加到 Java 的。
個人理解:
注解≈標簽
2、注解的使用場景?
我們先不談如何實現注解,我們從需求出發,先看看注解該如何使用。
- 生成文檔。這是最常見的,也是java 最早提供的注解。常用的有@param @return 等
- 跟蹤代碼依賴性,實現替代配置文件功能。比如Dagger 2依賴注入,未來java開發,將大量注解配置,具有很大用處;
- 在編譯時進行格式檢查。如@override 放在方法前,如果你這個方法並不是覆蓋了超類方法,則編譯時就能檢查出。
3、注解原理
注解本質是一個繼承了Annotation的特殊接口,其具體實現類是Java運行時生成的動態代理類。而我們通過反射獲取注解時,返回的是Java運行時生成的動態代理對象$Proxy1。通過代理對象調用自定義注解(接口)的方法,會最終調用AnnotationInvocationHandler的invoke方法。該方法會從memberValues這個Map中索引出對應的值。而memberValues的來源是Java常量池。
4、注解類型
- 元注解
- Java 內置注解
- 自定義注解
(1)元注解
- @Retention:描述注解生命周期,例如
@Retention(RetentionPolicy.RUNTIME)
- @Documented:將注解中的元素包含到
Javadoc
文檔中 - @Target:限定了注解作用的目標范圍,包括類、方法等等
- @Inherited:使得一個 被@Inherited注解的注解 作用的類的子類可以繼承該類的注解
- @Repeatable:使得作用的注解可以取多個值(Java1.8)
(2)Java 內置注解
- @Deprecated:標記已過時 & 被拋棄的元素(類、方法等)
- @Override:標記該方法需要被子類復寫
- @SuppressWarnings:標記的元素會阻止編譯器發出警告提醒 (主要應用於開發者需要忽略警告時)
- @SafeVarargs:提醒開發者不要用參數做不安全的操作 & 阻止編譯器產生
unchecked
警告(1.7引入) - @FunctionalInterface:表示該接口 = 函數式接口(1.8引入,例如
Runnable
接口就是使用了該注解)
(3)自定義注解
定義一個注解
// 通過 @interface 關鍵字進行定義
// 形式類似於接口,區別在於多了一個 @ 符號
public @interface MyAnnotation {
// 注解的屬性 = 成員變量
// 注解只有成員變量,沒有方法
// 注解@MyAnnotation中有2個屬性:id 和 msg
int id();
String msg() default "Hi" ;
// 說明:
// 注解的屬性以 “無形參的方法” 形式來聲明
// 方法名 = 屬性名
// 方法返回值 = 屬性類型 = 8 種基本數據類型 + 類、接口、注解及對應數組類型
// 用 default 關鍵值指定 屬性的默認值,如上面的msg的默認值 = ”Hi“
}
Demo地址如下:
https://github.com/Taoey/DAS/tree/master/JavaBase/src/main/java/annotation