java 註解(annotation)
阿新 • • 發佈:2019-02-15
一、概念:
註解相當於一種標記,在某一個程式上加了註解就相當於為這部分程式打了標記,該標記用來表示該程式段的特徵或形態。我們可以通過javac編譯器、開發工具、程式等使用反射機制來處理這些標記,對不同的標記去做一些不同的事。註解可以加在包、類、方法、方法引數、欄位、區域性變數等上面。
二、jdk預設提供註解:
在JDK5.0以後預設提供了三個常用的註解類: 1)、@Override:只能作用於方法之上,用來告訴別人這個方法是改寫父類的一個方法。 2)、@Deprecated:用於說明該程式元素已過時,可以作用於程式中任何元素之上,用 @Deprecated 註釋的程式元素,不鼓勵程式設計師使用,通常是因為它很危險或存在更好的選擇。在使用不被贊成的程式元素或在不被贊成的程式碼中執行重寫時,編譯器會發出警告。1.元註解說明: 元註解:就是專門用來定義註解的註解,主要作用就是用於約束自定義註解的功能。比如註解只能用在方法上、類上或欄位上等。
/* * JDK自帶的元註解有:@Target,@Retentio,@Documented,@Inherited * * @Target:指示該註解型別用於什麼元素之上,如果註解沒有新增@Target標示,則可以作用於任一程式元素上,如果加上了@Target註解型別約束,則編譯器會強制檢查作用於程式元素上的限制。 * 可選的ElementType註解型別包括: * ElementType.ANNOTATION_TYPE:只能作用於註解型別上 * ElementType.CONSTRUCTOR:只能作用於構造方法上 * ElementType.FIELD:只能作用於欄位上(包括列舉常量) * ElementType.LOCAL_VARIABLE:只能作用於區域性變數上 * ElementType.METHOD:只能作用於方法上 * ElementType.PACKAGE:只能作用於包上 * ElementType.PARAMETER:只能作用於方法引數宣告上 * ElementType.TYPE:只能作於類、介面、列舉、註解上 * * @Retention:指示在什麼級別保留註解資訊。如果註釋型別宣告中不存在Retention,則保留策略預設為 RetentionPolicy.CLASS。 * 可選的RetentionPolicy保留級別包括: * RetentionPolicy.SOURCE:僅保留在原始碼中,javac編譯完後,會丟棄註解。不會儲存在編譯好的class檔案上。 * RetentionPolicy.CLASS:保留在原始碼和class檔案中,jvm載入class位元組碼檔案時,不會載入註解。 * RetentionPolicy.RUNTIME:即保留在原始碼和class檔案中,也會被jvm載入到記憶體當中,所以可通過反射的方式讀取註解資訊。 * * @Documented:標示了此註解的元素,註釋將成為註解元素公共API的一部分。 * * @Inherited:指示註釋型別被自動繼承。如果在註釋型別宣告中存在 Inherited 元註釋,並且使用者在某一類宣告中查詢該註釋型別,同時該類宣告中沒有此型別的註釋,則將在該類的超類中自動查詢該註釋型別。此過程會重複進行,直到找到此型別的註釋或到達了該類層次結構的頂層 (Object) 為止。如果沒有超類具有該型別的註釋,則查詢將指示當前類沒有這樣的註釋。 */
2.下面看一個具體例子: a.建立一個註解:
package com.gyb.hello; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /* * 註解使用說明: 1、自定義的Annotation,隱式的繼續自java.lang.Annotation,所以不能在繼承其它的類或介面。 2、在Annotation中宣告的屬性方法只能是public的,或者預設不加訪問修飾符,(預設是public abstract)。 3、方法的返回值型別只限8種基本型別byte、int、short、long、float、double、char、boolean,和String、enum、annotation、Class,以及這些型別的陣列。 4、方法不能有引數 5、方法不能拋異常 */ @Target({ElementType.TYPE, ElementType.METHOD})//定義註解作用在類、介面等型別上和方法上 @Retention(RetentionPolicy.RUNTIME)//定義保留級別到執行時 public @interface MyAnnotation { /* * 這裡可以宣告多種型別的屬性方法以供我們實際應用中使用 */ String value() default "gyb"; //為屬性設定預設值 String color(); int[] arr() default {1,2,3,4,5,6}; //返回值型別為註解型別的屬性 //XXXXAnnotation annotationAttr(); }
b.註解使用和測試類:
package com.gyb.hello;
import java.lang.reflect.Method;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundOperation.ANONYMOUS;
@MyAnnotation(color="red",arr={8,9}) //另外兩個屬性已有預設值,這邊可以只對color屬性設值。
public class AnnotationTest {
@MyAnnotation(color="blue",value="hehe")
public void getInfo(){
System.out.println("hello annotation...");
}
public static void main(String args[]){
//判斷某個類中是否存在某個註解
if(AnnotationTest.class.isAnnotationPresent(MyAnnotation.class)){
//通過反射獲得類級別的註解資訊
MyAnnotation annotation = (MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);
System.out.println(annotation.color());//輸出red
System.out.println(annotation.value());//輸出預設值gyb
System.out.println(annotation.arr().length);//輸出設定的陣列長度2
}
//通過反射獲得方法級別的註解資訊(getInfo()方法)
Method m[] = AnnotationTest.class.getMethods();
for(Method method : m){
if(method.isAnnotationPresent(MyAnnotation.class)){//判斷某個方法中是否存在某註解
MyAnnotation annotation = (MyAnnotation)method.getAnnotation(MyAnnotation.class);
System.out.println(annotation.color());//輸出blue
System.out.println(annotation.value());//輸出hehe
System.out.println(annotation.arr().length);//輸出預設陣列長度6
}
}
}
測試結果:
red
gyb
2
blue
hehe
6
通告上面的例子我們對註解有了一個基本的瞭解,註解應該是以後的一個趨勢吧,目前spring、springmvc、struts2等開源框架中都引入了註解,註解的使用將會使我們的xml配置檔案大大縮減,而且能夠在一定程度上增加開發效率。