java 注解學習總結


Annotation(注解)是Java 1.5中添加的特性,很多java框架都依賴注解來實現代碼級配置,相比XML配置更簡潔。要理解框架的運行原理,注解是一個基礎的概念。

注解的基本概念

網上、書本對注解的基本概念已經進行了很詳細的講解,這里不再重述,例如:

《Java核心技術 卷2 10.3,10.4,10.5》對注解進行了全面的講解,但翻譯的文字晦澀
http://www.importnew.com/10294.html 講解了注解的基本概念,特別是介紹了注解的歷史
http://www.importnew.com/11908.html 對java8中對注解的改進進行了介紹

從高層次來講,注解是與代碼緊耦合的元數據;從語法上來看,注解是一種特殊的接口。

注解的生存期與注解的處理

注解的兩個元注解@Target@Retention定義了注解的使用目標和生存期。注解的生存期在java.lang.annotation.RetentionPolicy中進行了枚舉,包括:

  • SOURCE 存在源碼中,編譯階段被丟棄
  • CLASS 默認級別,存在類文件中,VM加載時將丟棄
  • RUNTIME 運行時,存在於運行時,可以通過反射API獲取

而處理注解的方式通常為以下幾種情況:

  • 使用javax.annotation.processing處理器API,在編譯前對注解進行處理,所有生存期的注解都能被處理;
  • 使用字節碼處理框架如bcel對class文件進行讀取並處理其中的注解,此時SOURCE級注解已經不存在;
  • 使用java.lang.instrument設備API,獲得class文件並處理其中的注解,此時SOURCE級注解已經不存在;
  • 使用java.lang.annotationAPI,獲取反射對象的注解並處理,此時SOURCE&CLASS級注解已經不存在。這是最常用的方式。

《Java核心技術 卷2》第10章節對上面方式都進行了介紹和基本實現。

元注解@Inherited

如果注解類型使用了@Inherited,聲明該注解的父類會將其注解繼承給子類。

下面用例子說明:
首先是注解類型Country用來聲明人所屬國家。

@Inherited
@Retention(RetentionPolicy.RUNTIME)//因為是運行時測試,所以需要讓注解在運行時保留
public @interface Country {
    String name();
}

然后是Chinese表示中國人,其所屬國家為China

/**
 * 中國人
 */
@Country(name = "China")
public class Chinese {
}

子類SiChuanese表示四川人。

/**
 * 四川人
 */
public class SiChuanese extends Chinese {
}

測試SiChuanese是否從其父類Chinese繼承了注解Country

public class CountryTest {
    @Test
    public void testCountry(){
        Assert.assertEquals("China",SiChuanese.class.getAnnotation(Country.class).name());//測試通過
    }
}

單值注解

可能好奇使用Spring框架時為什么當只需要一個元素時,可以省略元素名。如在Spring中:

@RequestMapping("/index")

這其實是注解的語法部分,叫做單值注解,特殊的value元素,當只指定該元素值時,可以省略元素名和等號。

參考《Java核心技術 卷2》 744頁

其實質等於:

@RequestMapping(value="/index")

又因為Spring使用自定義注解@AliasFor聲明了注解別名。因此等價於下面的注解:

@RequestMapping(name="/index")


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM