以下為本人的學習筆記 1.認識Annotation JDK1.5開始,java增加了對元數據(即類的組成單元數據)的支持,也就是(Annotation)註解,它是代碼里做的特殊標記,這些標記可以在編譯,類載入,運行時在不改變原有邏輯的情況下,被讀取(通過反射來讀取),並執行相應 的處理,通過使用An ...
以下為本人的學習筆記
1.認識Annotation
JDK1.5開始,java增加了對元數據(即類的組成單元數據)的支持,也就是(Annotation)註解,它是代碼里做的特殊標記,這些標記可以在編譯,類載入,運行時在不改變原有邏輯的情況下,被讀取(通過反射來讀取),並執行相應 的處理,通過使用Annotation,程式員可以在源文件中嵌入一些補充從信息。代碼分析工具,開發工具和部署工具可以通過這些補充信息進行驗證或者進行部署。Annotation類似於修飾符一樣被使用,可以用於包,類,構造方法,方法,成員變數,局部變數的聲明。
元數據可以說是一個屬性,解釋數據的數據。如一個屬性age的值為18,那麼這個解釋18的欄位age就是元數據。
註解也可以說是一個描述信息,把信息再解析。
註解的本質是標記,他所有的功能都依賴於對於這個註解解釋性的代碼,通常需要結合反射來編寫解釋下代碼。
註意:
Annotation是一個介面
java.lang.Annotation介面
2.系統定義的Annotation
在JDK1.5之後,在系統中提供了三個Annotation,分別是:@Override(譯:覆蓋)、@Deprecated(譯:已棄用)、@SupperssWarings。
@Override
表示驗證當前的方法是否覆蓋超類中的方法(即重寫父類方法)。如果你一不小心拼寫錯誤,或者方法簽名對不上被覆蓋的方法,編譯器就會發出錯誤提示
@Deprecated
表示的是一個類或方法已經不再建議繼續使用了,標記為已過時
@SupperssWarings
表示關閉不當的編譯器警告信息
Annotation | 說明 |
---|---|
@SupperssWarings("unchecked") | 未檢查的轉化,如集合沒有指定類型 |
@SupperssWarings("unused") | 未使用的變數 |
@SupperssWarings("resource") | 有泛型未指定類型 |
@SupperssWarings("path") | 在類路徑,原文件路徑中有不存在的路徑 |
@SupperssWarings("deprecation") | 使用了某些不贊成使用的類和方法 |
@SupperssWarings("fallthrough") | switch語句執行到底沒有break關鍵字 |
@SupperssWarings("serial") | 某類實現Serializable但是沒有定義serialVersionUID這個需要但是不必須的欄位 |
@SupperssWarings("rawtypes") | 沒有傳遞帶有泛型的參數 |
@SupperssWarings("all") | 全部類型的警告(用這一條就夠了) |
3.自定義Annotation
註解應用三個步驟:
1)編寫註解
2)在類上應用註解
3)對應用了註解的類進行反射操作的類
自定義Annotation的語法如下:
訪問控制許可權@interface Annotation 名稱{}
@interface : 定義一個註解的關鍵字
例如:
public @interface MyAnnotation{}
//1.自定義註解
//表示該註解的作用範圍在運行時存在
@Retention(RetentionPolicy.RUNTIME)
//用於生成文檔
@Documented
//用於表示註解的應用範圍(類型,方法,屬性,構造器,參數,局部變數,包,Annotation)
@Target(ElementType.TYPE)
@Inherited//子類可繼承
public @interface MyAnnotation{
//定義變數,註意:變數後要加括弧(),且調用此註解時必須設置變數名
public String name();
public int age() default 2;//給變數設置預設值
public String[] like();//定義一個數組,調用此註解時變數名要含大括弧{}
public COlor color();//定義一個枚舉類型的變數
}
public enum Color{
RED,GREEN,BLUE;
}
//2.使用註解
@MyAnnotation(name="wan",like = {"金魚","草魚"},color = Color.RED)
public class Cat{
private String name;
private int age;
public String[] like;
private Color color;
...(構造方法,getter(),setter())
}
public class AnnotationDemo{
/**
反射來處理註解
*/
@Test
public void test2(){
Class<Cat> catClass = Cat.class;
//獲取類上應用的指定註解
MyAnnotation annotation = CatClass.getAnnotation(MyAnnotation.class);
//獲取註解上變數值
String name = annotation.name();
int age = annotation.age();
Color color = annotation.color();
String[] like = annotation.like();
try{
//通過反射實例化對象,調用對象的方法存儲註解上的值
Cat cat =catClass.newInstance();
cat.setName(name);
cat.setAge(age);
cat.setLike(like);
cat.setColor(color);
System.out.println(cat);
}catch(InstantiationException e){
e.printStackTrace();
}catch(IllegalAccessException e){
e.printStackTrace();
}
}
}
4.Retention和RetentionPolicy
Annotation要想決定其作用的範圍,通過@Retention(譯:保持)指定,而Retention指定的範圍由RetentionPolicy(policy,譯:方針,政策,原則)決定,RetentionPolicy指定了三種範圍:
範圍 | 說明 |
---|---|
public static final RetentionPolicy SOURCE | 在java源程式中存在(提供給編譯器使用) |
public static final RetentionPolicy CLASS | 在java生成的class存在 |
public static final RetentionPolicy RUNTIEM | 在java運行的時候存在(我們通常使用這個範圍) |
示例:
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation{
public String name();
}
5.反射與Annotation
一個Annotation真正起作用,必須結合反射機制,在反射中提供了以下的操作方法:
java.lang.reflect.AccessibleObject(供虛擬機使用)
說明 | |
---|---|
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) (present,譯:目前,出現) | 判斷是否是指定的Annotation |
public Annotation[] getAnnotations() | 得到全部的Annotation |
public Annotation getAnnotation(Annotation.class) |
註解在目前而言最主流的應用就是代替配置文件,例如Spring、SpringBoot等,註解具有開發效率高,成本低的特點,缺點是耦合性高,不利於維護
6.@Documented註解
此註解表示的是文檔化,可以在生成doc文檔的時候添加註解,即生成文檔時,註釋一起生成
7.@Target註解
@Target註解(用來註釋註解)表示的是一個Annotation的使用範圍,例如:之前定義的MyAnnotation可以在任意的位置上使用(沒有寫這個註解,就所有地方可以使用)
範圍 | 說明 |
---|---|
public static final ElementType TYPE | 只能在類或介面或枚舉上使用 |
public static final ElementType FIELD | 在成員變數中使用 |
public static final ElementType METHOD | 在方法中使用 |
public static final ElementType PARAMETER | 在參數上使用 |
public static final ElementType CONSTRUCTOR | 在構造中使用 |
public static final ElementType | 局部變數上使用 |
public static final ElementType ANNOTATION_TYPE | 只能在Annotation中使用 |
public static final ElementType PACKAGE | 只能在包中使用 |
8.@Inherited註解
9.面試題:
從 JDK 5.0 開始, Java 增加了對元數據(MetaData) 的支持, 也就是Annotation(註解)。
Annotation 其實就是代碼里的特殊標記, 這些標記可以在編譯, 類載入, 運行時被讀取, 並執行相應的處理。
Annotation 可以像修飾符一樣被使用, 可用於修飾包, 類, 構造器, 方法, 成員變數, 參數, 局部變數的聲明, 這些信息被保存在Annotation 的 “name=value” 對中。
2、JAVASE常用的註解?
@Override: 限定重寫父類方法, 該註解只能用於方法;在編譯期檢測是否是重寫的方法;
@Deprecated: 用於表示所修飾的元素(類, 方法等)已過時。通常是因為所修飾的結構危險或存在更好的選擇;
@SuppressWarnings: 抑制編譯器警告;
3、怎麼自定義註解?
1)、定義新的 Annotation 類型使用 @interface 關鍵字,自定義註解自動繼承了java.lang.annotation.Annotation介面。
2)、Annotation 的成員變數在 Annotation 定義中以無參數方法的形式來聲明。其方法名和返回值定義了該成員的名字和類型。我們稱為配置參數。類型只能是八種基本數據類型、String類型、Class類型、enum類型、Annotation類型、以及所有類型的數組。
3)、我們自定義的註解,如果有成員變數,那麼在使用的時候必須賦值;如果自定義的註解的成員變數,賦予了預設值,那麼我們使用的時候可以賦值,也可以不賦值; 我們需要default來給註解的成員變數賦值
4)、如果只有一個參數成員,建議使用參數名為value;
5)、沒有成員定義的 Annotation 稱為標記; 包含成員變數的 Annotation 稱為元數據 Annotation; 我們都可以稱之為註解;
4、什麼元註解,元註解有哪些,作用是什麼?
JDK 的元 Annotation 用於修飾其他 Annotation 定義;
@Retention: 只能用於修飾一個 Annotation 定義, 用於指定該 Annotation 的生命周期, @Rentention 包含一個RetentionPolicy 類型的成員變數, 使用@Rentention 時必須為該 value 成員變數指定值: RetentionPolicy.SOURCE:在源文件中有效(即源文件保留),編譯器直接丟棄這種策略的註釋;
RetentionPolicy.CLASS:在class文件中有效(即class保留),當運行 Java 程式時, JVM 不會保留註解。 這是預設值;
RetentionPolicy.RUNTIME:在運行時有效(即運行時保留),當運行 Java 程式時, JVM 會保留註釋。程式可以通過反射獲取該註釋。
@Target: 用於修飾 Annotation 定義, 用於指定被修飾的 Annotation 能用於修飾哪些程式元素。 @Target 也包含一個名為 value 的成員變數。
@Documented: 用於指定被該元 Annotation 修飾的 Annotation 類將被javadoc 工具提取成文檔。預設情況下,javadoc是不包括註解的。
@Inherited: 被它修飾的 Annotation 將具有繼承性。
■免責申明
⒈ 本站是純粹個人學習網站,與朋友交流共賞,不存在任何商業目的。
⒉ 本站利用了部分網路資源,版權歸原作者及網站所有,如果您對本站所載文章及作品版權的歸屬存有異議,請立即通知我們,我們將在第一時間予以刪除,同時向你表示歉意!