Java Annotation 必須掌握的特性
什麼是Annotation?
Annotation翻譯為中文即為註解,意思就是提供除了程式本身邏輯外的額外的資料資訊。Annotation對於標註的程式碼沒有直接的影響,它不可以直接與標註的程式碼產生互動,但其他元件可以使用這些資訊。
Annotation資訊可以被編譯進class檔案,也可以保留在Java 虛擬機器中,從而在執行時可以獲取。甚至對於Annotation本身也可以加Annotation。
那些物件可以加Annotation
類,方法,變數,引數,包都可以加Annotation。
內建的Annotation
@Override 過載父類中方法 @Deprecated 被標註的方法或型別已不再推薦使用
@SuppressWarnings 阻止編譯時的警告資訊。其需要接收一個String的陣列作為引數。 可供使用的引數有:
- unchecked
- path
- serial
- finally
- fallthrough
可以用與其他annotation上的annotation
@Retention
確定Annotation被儲存的生命週期, 需要接收一個Enum物件RetentionPolicy作為引數。
public enum RetentionPolicy { /** * Annotations are to be discarded by the compiler. */ SOURCE, /** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */ CLASS, /** * Annotations are to be recorded in the class file by the compiler and * retained by the VM at run time, so they may be read reflectively. * * @see java.lang.reflect.AnnotatedElement */ RUNTIME }
@Documented 文件化
@Target
表示該Annotation可以修飾的範圍,接收一個Enum物件EnumType的陣列作為引數。
public enum ElementType { /** Class, interface (including annotation type), or enum declaration */ TYPE, /** Field declaration (includes enum constants) */ FIELD, /** Method declaration */ METHOD, /** Parameter declaration */ PARAMETER, /** Constructor declaration */ CONSTRUCTOR, /** Local variable declaration */ LOCAL_VARIABLE, /** Annotation type declaration */ ANNOTATION_TYPE, /** Package declaration */ PACKAGE }
@Inherited
該Annotation可以影響到被標註的類的子類。
自定義Annotation
JSE5.0以後我們可以自定義Annotation。下面就是一個簡單的例子。
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MethodAnnotation { }
下面的Person物件使用了自定義的MethodAnnotation。
public class Person { public void eat() { System.out.println("eating"); } @MethodAnnotation public void walk() { System.out.print("walking"); } }
我們可以通過反射獲取Annotation的資訊。
Class<Person> personClass = Person.class; Method[] methods = personClass.getMethods(); for(Method method : methods){ if (method.isAnnotationPresent(MethodAnnotation.class)){ method.invoke(personClass.newInstance()); } }
輸出:
walking
我們也可以給自定義的Annotation加方法。
@Target(ElementType.TYPE) public @interface personAnnotation { int id() default 1; String name() default "bowen"; }
下面是對personAnnotation的使用。
@personAnnotation(id = 8, name = "john") public class Person { public void eat() { System.out.println("eating"); } @MethodAnnotation public void walk() { System.out.print("walking"); } }
Annotation是如何被處理的
當Java原始碼被編譯時,編譯器的一個外掛annotation處理器則會處理這些annotation。處理器可以產生報告資訊,或者建立附加的Java原始檔或資源。如果annotation本身被加上了RententionPolicy的執行時類,則Java編譯器則會將annotation的後設資料儲存到class檔案中。然後,Java虛擬機器或其他的程式可以查詢這些後設資料並做相應的處理。
當然除了annotation處理器可以處理annotation外,我們也可以使用反射自己來處理annotation。Java SE 5有一個名為AnnotatedElement的介面,Java的反射物件類Class,Constructor,Field,Method以及Package都實現了這個介面。這個介面用來表示當前執行在Java虛擬機器中的被加上了annotation的程式元素。通過這個介面可以使用反射讀取annotation。AnnotatedElement介面可以訪問被加上RUNTIME標記的annotation,相應的方法有getAnnotation,getAnnotations,isAnnotationPresent。由於Annotation型別被編譯和儲存在二進位制檔案中就像class一樣,所以可以像查詢普通的Java物件一樣查詢這些方法返回的Annotation。
Annotation的廣泛使用
Annotation被廣泛用於各種框架和庫中,下面就列舉一些典型的應用.
Junit
Junit是非常著名的一款單元測試框架,使用Junit的時候需要接觸大量的annotation。
- @Runwith 自定義測試類的Runner
- @ContextConfiguration 設定Spring的ApplicationContext
- @DirtiesContext 當執行下一個測試前重新載入ApplicationContext.
- @Before 呼叫測試方法前初始化
- @After 呼叫測試方法後處理
- @Test 表明該方法是測試方法
- @Ignore 可以加在測試類或測試方法上,忽略執行。
- @BeforeClass:在該測試類中的所有測試方法執行前呼叫,只被呼叫一次(被標註的方法必須是static)
- @AfterClass:在該測試類中的所有的測試方法執行完後呼叫,只被執行一次(被標註的方法必須是static)
Spring
Spring 號稱配置地獄,Annotation也不少。
- @Service 給service類加註解
- @Repository 給DAO類加註解
- @Component 給元件類加註解
- @Autowired 讓Spring自動裝配bean
- @Transactional 配置事物
- @Scope 配置物件存活範圍
- @Controller 給控制器類加註解
- @RequestMapping url路徑對映
- @PathVariable 將方法引數對映到路徑
- @RequestParam 將請求引數繫結到方法變數
- @ModelAttribute 與model繫結
- @SessionAttributes 設定到session屬性
Hibernate
- @Entity 修飾entity bean
- @Table 將entity類與資料庫中的table對映起來
- @Column 對映列
- @Id 對映id
- @GeneratedValue 該欄位是自增長的
- @Version 版本控制或併發性控制
- @OrderBy 排序規則
- @Lob 大物件標註
Hibernate還有大量的關於聯合的annotation和繼承的annotation,這裡就不意義列舉了。
JSR 303 – Bean Validation
JSR 303 – Bean Validation是一個資料驗證的規範,其對Java bean的驗證主要通過Java annotation來實現。
- @Null被註釋的元素必須為 null
- @NotNull被註釋的元素必須不為 null
- @AssertTrue被註釋的元素必須為 true@AssertFalse被註釋的元素必須為 false@Min(value)被註釋的元素必須是一個數字,其值必須大於等於指定的最小值
- @Max(value)被註釋的元素必須是一個數字,其值必須小於等於指定的最大值
- @DecimalMin(value)被註釋的元素必須是一個數字,其值必須大於等於指定的最小值
- @DecimalMax(value)被註釋的元素必須是一個數字,其值必須小於等於指定的最大值
- @Size(max, min)被註釋的元素的大小必須在指定的範圍內
- @Digits (integer, fraction)被註釋的元素必須是一個數字,其值必須在可接受的範圍內
- @Past被註釋的元素必須是一個過去的日期
- @Future被註釋的元素必須是一個將來的日期
- @Pattern(value)被註釋的元素必須符合指定的正規表示式
其實還有很多使用了annotaion的framework或library,這裡就不一一列舉了,希望大家能舉一反三,深入瞭解Java中的annotation。
相關文章
- Java必須掌握的Spring常用註解JavaSpring
- Git中~你必須掌握的!Git
- Java經典常用類總結(必須掌握!)Java
- Java開發必須掌握的線上問題排查命令Java
- Java 程式設計師必須掌握的 Linux 命令Java程式設計師Linux
- CSS中那些必須掌握的概念CSS
- 前端必須掌握的知識點前端
- java開發必須要掌握的20個核心技術Java
- JVM-Java工程師必須掌握的知識點JVMJava工程師
- 【4】進大廠必須掌握的面試題-Java面試-jdbc面試題JavaJDBC
- Java程式設計師必須掌握的5個註解!Java程式設計師
- Java程式設計師面試必須要掌握的面試題Java程式設計師面試題
- Java程式設計師必須掌握的7個Java效能指標!Java程式設計師指標
- 學習Linux必須掌握的命令!Linux
- 必須掌握的10個Linux命令!Linux
- git 必須要熟練掌握的命令Git
- 【5】進大廠必須掌握的面試題-Java面試-spring面試題JavaSpring
- Java程式設計師必須掌握的Spring依賴管理原理Java程式設計師Spring
- 必須掌握的Linux使用者組Linux
- JavaScript必須要掌握的知識-作用域JavaScript
- AS3開發必須掌握的內容S3
- 列舉幾個Java程式設計師通用的、必須掌握的框架Java程式設計師框架
- Java開發者必須掌握的15個框架(20k是小問題)Java框架
- 面試阿里P6,Java程式設計師必須掌握的技術面試阿里Java程式設計師
- Java程式設計師必須掌握的8大排序演算法Java程式設計師排序演算法
- Java碼農必須掌握的迴圈刪除List元素的正確方法Java
- 技術人必須掌握能力——深度思考
- Linux必須掌握的shell指令碼基礎Linux指令碼
- C語言必須掌握的判斷題 | 4C語言
- C語言必須掌握的判斷題 | 10C語言
- 外貿小白必須掌握的基礎知識
- 6. 你必須掌握Dart中的陣列Dart陣列
- shell程式設計必須要掌握的命令-xargs程式設計
- 學習web前端,必須要掌握的CSS原理Web前端CSS
- Linux系統中必須掌握的特殊字元!Linux字元
- sed、awk——運維必須掌握的兩個工具運維
- 前端工程師必須掌握的設計模式前端工程師設計模式
- mysql 必須掌握的工具pt-query-digestMySql