1. 程式人生 > >java 註解(annotation)

java 註解(annotation)

一、概念:

註解相當於一種標記,在某一個程式上加了註解就相當於為這部分程式打了標記,該標記用來表示該程式段的特徵或形態。我們可以通過javac編譯器、開發工具、程式等使用反射機制來處理這些標記,對不同的標記去做一些不同的事。註解可以加在包、類、方法、方法引數、欄位、區域性變數等上面。

二、jdk預設提供註解:

在JDK5.0以後預設提供了三個常用的註解類: 1)、@Override:只能作用於方法之上,用來告訴別人這個方法是改寫父類的一個方法。 2)、@Deprecated:用於說明該程式元素已過時,可以作用於程式中任何元素之上,用 @Deprecated 註釋的程式元素,不鼓勵程式設計師使用,通常是因為它很危險或存在更好的選擇。在使用不被贊成的程式元素或在不被贊成的程式碼中執行重寫時,編譯器會發出警告。
3)、@SuppressWarnings:用於關閉編譯器提示的警告資訊。 三、自定義註解:
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配置檔案大大縮減,而且能夠在一定程度上增加開發效率。