Annotation簡介:
Annotation提供一種機制,將程序中元素(如類、方法、屬性等)和元數據聯系起來。這樣編譯器可以將元數據保存的class文件中。代碼分析工具就可以使用這些元數據執行的額外任務。注釋采用“at”標記形式 ( @ ),后面是注釋名稱。
自定義 annotationDebug.java
package annotation.test;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;


/**//*
* annotation類型是一種接口,能夠通過java反射API的方式提供對其信息的訪問
*/


/**//*
* Documented 產生Java Doc文件,這次可以看到文件中包括了@Debug的信息
*/
@Documented

/**//*
* 限定 annotation 使用對象 - Target
* 在定義annotation時,使用java.lang.annotation.Target可以定義annotation使用的時機。
* public enum ElementType {
* TYPE, // 適用 class, interface, enum
* FIELD, // 適用 field
* METHOD, // 適用 method
* PARAMETER, // 適用 method 上之 parameter
* CONSTRUCTOR, // 適用 constructor
* LOCAL_VARIABLE, // 適用區域變量
* ANNOTATION_TYPE, // 適用 annotation 型態
* PACKAGE // 適用 package
* }
*/

@Target(
{ElementType.CONSTRUCTOR, ElementType.METHOD})//指定目標

/**//*
* Retention 在你自定義的形態中,指定編譯器如何處理自定義的annotation
* 告知編譯器如何處理 annotaion - Retention
* RetentionPolicy
* SOURCE 編譯器處理完Annotation信息后就沒事了
* CLASS 編譯器將Annotation儲存于class檔中,預設
* RUNTIME 編譯器將Annotation儲存于class檔中,可由VM讀入
* 使用java設計的一個程序代碼工具,從VM中讀出Annotation信息,已在分析程序中使用。
* 搭配Reflection機制,就可以實現。
*
* J2SE 5.0中新增了java.lang.reflect.AnnotatedElement這個接口,當中定義有四個方法:
* public Annotation getAnnotation(Class annotationType);
* public Annotation[] getAnnotations();
* public Annotation[] getDeclaredAnnotations();
* public boolean isAnnotationPresent(Class annotationType);
* Class、Constructor、Field、Method、Package等類別,都實作了 AnnotatedElement這個接口,
* 所以您可以從這些類別的實例上,分別取得標示于其上的Annotation與其信息,
* 如果 RetentionPolicy為RUNTIME的話。

*/
@Retention(RetentionPolicy.RUNTIME)//設置保持性

/**//*
* @Inherited 子類是否繼承父類的 annotation
*/
@Inherited

public @interface Debug
{
//定義了value()方法,編譯器在編譯時會自動幫您產生一個value的變量成員,接著在使用Debug Annotation時要指定值
//注釋類型的數據成員被設置成使用有限信息進行工作
//定義數據成員不需要分別定義訪問和修改的方法,只需定義一個方法,以數據成員的名稱命名它,數據類型應該是該方法返回值的類型.
String value()default "windfree";//默認值的類型必需與成員變量的申明類型一置
String name();
}


在程序中使用自定義的annotation
TestDebug.java
package annotation.test;


public class TestDebug
{
@Debug(
name = "zgliu"
)

public void doSomething()
{
}
}

使用java中反射API讀取class中的元數據的信息
DebugTool.java:
package annotation.test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;


public class DebugTool
{

public static void main(String []args)throws NoSuchMethodException
{
Class<TestDebug> c=TestDebug.class;
Method method = c.getMethod("doSomething");

if(method.isAnnotationPresent(Debug.class))
{
System.out.println("@Debug is found.");
Debug debug = method.getAnnotation(Debug.class);
System.out.println("\tvalue = " + debug.value());
System.out.println("\tname = " + debug.name());
}

else
{
System.out.println("@Debug is not found.");
}

Annotation[] annotations = method.getAnnotations();

for(Annotation annotation : annotations)
{
System.out.println(
annotation.annotationType().getName());
}
}
}
Java標準Annotation
@Deprecated 相當于Javadoc的@deprecated,被@Deprecated標注的對象class, method等被注明為不推薦使用。主要用于javac等編譯工具。
@Override 注明對象method重載了父類的方法。javac等編譯工具編譯時會根據此Annotation判斷重載方法是否正確。
@SuppressWarnings 告訴javac等編譯器忽略所指定的特定的警告信息。
@Target 被定義的annotation可以附加在那些對象上。
@Retention annotation的作用期間。
定義一個annotation
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)

public @interface MyAnnotation
{①定義一個注釋
int init();
}

import java.lang.annotation.Annotation;

public class TestAnnotation
{
@MyAnnotation(init = 2)②使用注釋

public void print()
{
System.out.println(TestAnnotation.class.getName());
}

public static void main(String[] args) throws Exception
{
TestAnnotation ta = new TestAnnotation();
Annotation[] annotations = ta.getClass().getMethod("print").getAnnotations();③

for (Annotation annotation : annotations)
{
System.out.println("MyAnnotation.init : " +
((MyAnnotation)annotation).init());④打印出init的值
}
}
}

我們定義了一個名為MyAnnotation的注釋而這個注釋中只有一個類型為int名為init的屬性,我們在②處使用了我們剛剛定義的注釋并且為init賦值為2,在③處我們通過反射機制獲得print方法上定義的所有注釋然后通過迭代將其值init打印至控制臺。
最終在控制臺輸出以下信息:
MyAnnotation.init : 2