1.什麼是註解
2.基本的Annotation
1.限定父類重寫方法:@Override
當子類重寫父類方法時,子類可以加上這個註解,那這有什麼什麼用?這可以確保子類確實重寫了父類的方法,避免出現低級錯誤
2.標示已過時:@Deprecated
List list = new ArrayList();
list.add(20);
List<String> ls = list;
System.out.println(ls.get(0));
則會拋出堆污染異常
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at Test.Test1.main(Test1.java:29)
注意:可變參數更容易引發堆污染異常,因爲java不允許創建泛型數組,可變參數恰恰是數組。抑制這個警告的方法有三個:
3.自定義註解
1.定義註解非常的簡單,如下
public @interface Test{}然後這個註解就可以用在別的地方
4.JDK的元Annotation
1.使用@Retention
這個註解是用來修飾註解定義的,作用是被修飾的註解可以保存多久,這個註解需要使用參數。
這個參數的類型是RetentionPolicy,所以使用這個註解就要對value賦值。
value的值有且僅有三個:
->RetenionPolicy.CLASS 編譯器把該註解記錄在class文件中。當運行java程序時,JVM不可獲取註解信息。這是默認值!
->RetenionPolicy.RUNTIME 編譯器把該註解記錄在class文件中。當運行java程序時,JVM可獲取註解信息,程序可以通過反射獲取該註解信息
->RetenionPolicy.SOURCE 該註解只保存在源代碼中,編譯器直接丟棄該註解
例如:@Retention(value = RetenionPolicy.SOURCE ) 可簡寫爲 @Retention(RetenionPolicy.SOURCE )
2.使用@Target
@Target也只能修飾一個註解定義,作用是指定被修飾的註解能用於修飾哪些程序單元,@Target也包含了一個value值,他的值只能是下面的:ElementType.
取值 | 註解使用範圍 |
METHOD | 可用於方法上 |
TYPE | 可用於類或者接口上 |
ANNOTATION_TYPE | 可用於註解類型上(被@interface修飾的類型) |
CONSTRUCTOR | 可用於構造方法上 |
FIELD | 可用於域上 |
LOCAL_VARIABLE | 可用於局部變量上 |
PACKAGE | 用於記錄java文件的package信息 |
PARAMETER | 可用於參數上 |
例如:
@Target(ElementType.METHOD) (這是簡寫)
public @interface Action()
@interface 不是interface,是註解類
是jdk1.5之後加入的,java沒有給它新的關鍵字,所以就用@interface 這麼個東西表示了
這個註解類,就是定義一個可用的註解,包括這個註解用於什麼地方,是類,還是方法,還是property,還是方法入參等等,還有這個註解是否編譯後進入class
比如我們知道的用於javadoc的註解,是不進入class文件的。然後在後面你就可以用這個註解寫代碼了。
總的來說,這就是一個生成javadoc時用到的註釋類
3.使用@Documented
這個註解用於指定被修飾的註解類將被javadoc工具提取成文檔,如果定義註解類時使用了這個註解修飾,則所有使用該註解修飾的程序員蘇API文檔將會包含該註解說明。
例如:
@Documented public @interface Testable{}
4.使用@Inherited
這個註解指定被他修飾的註解將具有繼承性——如果某個類使用了@Xxx,則其子類將自動被@Xxx修飾
5.使用@Result
作用是在同一個程序元素前使用多個相同類型的註解
在java8之前只能通過@Results配置,java8簡化了它的寫法
例如:
@test(age=5)
@test(age=8)
public void resultTest(){}
6.使用類型註解
讓我們先看幾個例子:
- 創建類實例
new@Interned MyObject();
- 類型映射
myString = (@NonNull String) str;
- implements 語句中
class UnmodifiableList<T> implements@Readonly List<@Readonly T> { ... }
- throw exception聲明
等等地方都可以用類型註解void monitorTemperature() throws@Critical TemperatureException { ... }
新增ElementType.TYPE_USE 和ElementType.TYPE_PARAMETER(在Target上)
新增的兩個註釋的程序元素類型 ElementType.TYPE_USE 和 ElementType.TYPE_PARAMETER用來描述註解的新場合。 ElementType.TYPE_PARAMETER 表示該註解能寫在類型變量的聲明語句中。 ElementType.TYPE_USE 表示該註解能寫在使用類型的任何語句中(eg:聲明語句、泛型和強制轉換語句中的類型)。還是那句話,這些註解本身是沒有意義的。要靠自己實現類型註解的檢查框架,或者第三方,類型註解最大的意義在於,讓編譯器執行更嚴格的檢查,保證代碼更加的健壯。