首頁 >Java >java教程 >Java 什麼是註解及註解原理詳細介紹

Java 什麼是註解及註解原理詳細介紹

高洛峰
高洛峰原創
2017-01-23 15:29:041503瀏覽

什麼是註解

註解也叫元數據,例如我們常見的@Override和@Deprecated,註解是JDK1.5版本開始引入的一個特性,用於對程式碼進行說明,可以對套件、類別、介面、字段、方法參數、局部變數等進行註解。它主要的功能有以下四個面向:

產生文檔,透過程式碼裡標識的元資料產生javadoc文檔。

編譯檢查,透過程式碼裡標識的元資料讓編譯器在編譯期間進行檢查驗證。

編譯時動態處理,編譯時透過程式碼裡標識的元資料動態處理,例如動態產生程式碼。

運行時動態處理,運行時透過程式碼裡標識的元資料動態處理,例如使用反射注入實例。

一般註解可分為三類:

一類是Java自帶的標準註解,包括@Override、@Deprecated和@SuppressWarnings,分別用於標明重寫某個方法、標明某個類或方法過時、標示要忽略的警告,用這些註解標明後編譯器就會進行檢查。

一類為元註解,元註解是用於定義註解的註解,包括@Retention、@Target、@Inherited、@Documented,@Retention用於標明註解被保留的階段,@Target用於標明註解使用的範圍,@Inherited用來標示註解可繼承,@Documented用於標明是否產生javadoc文件。

一類為自訂註解,可依自己的需求定義註解,並可用元註解對自訂註解進行註解。

註解原理:

看看在Java的大體系下面是如何對註解的支持的。還是回到上面自訂註解的例子,對於註解Test,如下,如果對AnnotationTest類別進行註解,則執行時可以透過AnnotationTest.class.getAnnotation(Test.class)取得註解宣告的值,從上面的句子就可以看出,它是從class結構中獲取出Test註解的,所以肯定是在某個時候註解被加入到class結構中去了。

@Test("test")
public class AnnotationTest {
public void test(){
}
}

從java源碼到class字節碼是由編譯器完成的,編譯器會對java源碼進行解析並產生class文件,而註解也是在編譯時由編譯器進行處理,編譯器會對註解符號處理並且附加到class結構中,根據jvm規範,class檔案結構是嚴格有序的格式,唯一可以附加資訊到class結構中的方式就是儲存到class結構的attributes屬性中。我們知道對於類別、欄位、方法,在class結構中都有自己特定的表格結構,而且各自都有自己的屬性,而對於註解,作用的範圍也可以不同,可以作用在類別上,也可以作用在在欄位或方法上,這時編譯器會對應到將註解資訊存放到類別、欄位、方法自己的屬性上。

在我們的AnnotationTest類別被編譯後,在對應的AnnotationTest.class檔案中會包含一個RuntimeVisibleAnnotations屬性,由於這個註解是作用在類別上,所以此屬性被加入到類別的屬性集上。即Test註解的鍵值對value=test會被記錄起來。而當JVM載入AnnotationTest.class檔案位元組碼時,就會將RuntimeVisibleAnnotations屬性值儲存到AnnotationTest的Class物件中,於是就可以透過AnnotationTest.class.getAnnotation(Test.class)取得到Test註解對象,進而再透過Test註解物件取得到Test裡面的屬性值。

這裡可能會有疑問,Test註解對像是什麼?其實註解被編譯後的本質就是一個繼承Annotation接口的接口,所以@Test其實就是“public interface Test extends Annotation”,當我們透過AnnotationTest.class.getAnnotation(Test.class)呼叫時,JDK會透過動態代理產生一個實作了Test介面的對象,並把將RuntimeVisibleAnnotations屬性值設定進此對像中,此對象即為Test註解對象,透過它的value()方法就可以取得到註解值。 

Java註解實作機制的整個過程如上所示,它的實作需要編譯器和JVM一起配合。

感謝閱讀,希望能幫助大家,謝謝大家對本站的支持!

更多Java 什麼是註解及註解原理詳細介紹相關文章請關注PHP中文網!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn