Java Annotation —— 註解實戰

        Annotation是Java5、6只後的新特徵(中文稱之爲註解),並且越來越多的得到了應用,比如Spring、Hibernate3、Struts2、iBatis3、JPA、JUnit等等都得到了廣泛應用,通過使用註解,代碼的靈活性大大提高。這些都是使用別人定義的註解,一般註解的使用都是在一些基礎框架或者類庫中來定義的,因此很少見過有人自己去寫一個注解出來並使用在程序中。
一、註解的好處在於

       通過類似註釋的方式,可以控制程序的一些行爲,運行時的狀態,可以爲成員賦值,做配置信息等等,與常規編碼思維大相徑庭。只用別人定義好的註解是搞不懂這些問題的,要想真正知道註解內部的祕密,要自己定義註解,然後在程序中獲取註解信息,拿到註解信息後,就可以爲我所用了。
下面我簡單演示下三類註解的用法:類註解、方法註解、字段(也稱之域)註解的定義與適用,並看看如何獲取註解的信息。

二、使用注意點

(1)自定義註解,注意註解的時空範圍,簡單說就是註解針對的目標(類、方法、字段),以及註解的時效(運行時、或者源碼中有效)。
(2)要獲取註解的信息,必須通過Java的反射技術來獲取Annotation對象,因爲你除此之外沒有別的獲取註解對象的方法。
(3)獲取了註解對象,就可以調用註解的方法來獲取相對應的值了。爲基礎框架所用。
(4)當然,註解也可以沒有定義成員,這樣註解就成了一個標記符號了。

三、代碼實戰:

(1)AnnotationInterfaceFIELD.java

package com.demo.annotation;

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Inherited
@Documented
public @interface AnnotationInterfaceFIELD {
	public String descriptionFIELD();
}
(2)AnnotationInterfaceMETHOD.java

package com.demo.annotation;

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
@Documented
public @interface AnnotationInterfaceMETHOD {
	public String descriptionMETHOD();
}
(3)AnnotationInterfaceTYPE.java
package com.demo.annotation;

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

//@Retention(value=RetentionPolicy.RUNTIME)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
//@Target({ElementType.FIELD, ElementType.METHOD})
@Inherited
@Documented
public @interface AnnotationInterfaceTYPE {
	String name() default "bob";
	int age() default 24; 
}
(4)AnnotationTestClass.java
package com.demo.annotation;

@AnnotationInterfaceTYPE(name="chy龍神的博客",age=24)
public class AnnotationTestClass {
	
	@AnnotationInterfaceFIELD(descriptionFIELD="annotation private field")
	private String privateField;
	
	@AnnotationInterfaceFIELD(descriptionFIELD="annotation protected field")
	protected String protectedField;
	
	@AnnotationInterfaceFIELD(descriptionFIELD="annotation public field")
	public String publicField;
	
	@AnnotationInterfaceMETHOD(descriptionMETHOD="annotation private method")
	public void privateMethod() { }
	
	@AnnotationInterfaceMETHOD(descriptionMETHOD="annotation protected method")
	public void protectedMethod() { }
	
	@AnnotationInterfaceMETHOD(descriptionMETHOD="annotation public method")
	public void publicMethod() { }
}
(5)AnnotationTestDemo

package com.demo.annotation;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class AnnotationTestDemo {

	public static void main(String[] args) {
		AnnotationTestClass cls = new AnnotationTestClass();
		try {
			Class annotationCls = Class.forName("com.demo.annotation.AnnotationInterfaceTYPE");
			if(cls.getClass().isAnnotationPresent(annotationCls)) {
				System.out.println("\nAnnotation Type=====================");
				AnnotationInterfaceTYPE annotationType = cls.getClass().getAnnotation(AnnotationInterfaceTYPE.class);
				System.out.println("annotationType.name = " + annotationType.name());
				System.out.println("annotationType.name = " + annotationType.age());
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		System.out.println("\nAnnotation Field====================");
		//getField只能獲取類的public字段
		Field[] fields = cls.getClass().getFields();
		System.out.println("1、getField"+"("+fields.length+")");
		dumpFields(fields);
		
		//getDeclaredField是可以獲取一個類的所有字段
		Field[] declardFields = cls.getClass().getDeclaredFields();
		System.out.println("\n2、getDeclaredField"+"("+declardFields.length+")");
		dumpFields(declardFields);
		
		try {
			Field mField = cls.getClass().getDeclaredField("publicField");
			AnnotationInterfaceFIELD mAnnotationField = mField.getAnnotation(AnnotationInterfaceFIELD.class);
			System.out.println(mAnnotationField.descriptionFIELD());
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		}
			
		System.out.println("\nAnnotation Method===================");
		Method[] methods = cls.getClass().getMethods();
		System.out.println("1、getMethod"+"("+methods.length+")");
		dumpMethods(methods);
		
		Method[] declardMethods = cls.getClass().getDeclaredMethods();
		System.out.println("\n2、getDeclaredMethod"+"("+declardMethods.length+")");
		dumpMethods(declardMethods);
		
		try {
			Method mMethod = cls.getClass().getDeclaredMethod("publicMethod");
			AnnotationInterfaceMETHOD mAnnotatMethod = mMethod.getAnnotation(AnnotationInterfaceMETHOD.class);
			System.out.println(mAnnotatMethod.descriptionMETHOD());
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
	}
	
	public static void dumpFields(Field[] fields) {
		for(int i=0;i<fields.length;i++) {
			System.out.println("("+i+")"+fields[i].getName());
		}
	}
	
	public static void dumpMethods(Method[] methods) {
		for(int i=0;i<methods.length;i++) {
			System.out.println("("+i+")"+methods[i].getName());
		}
	}
}

        Annotation是Java5、6只後的新特徵(中文稱之爲註解),並且越來越多的得到了應用,比如Spring、Hibernate3、Struts2、iBatis3、JPA、JUnit等等都得到了廣泛應用,通過使用註解,代碼的靈活性大大提高。這些都是使用別人定義的註解,一般註解的使用都是在一些基礎框架或者類庫中來定義的,因此很少見過有人自己去寫一個注解出來並使用在程序中。
一、註解的好處在於

       通過類似註釋的方式,可以控制程序的一些行爲,運行時的狀態,可以爲成員賦值,做配置信息等等,與常規編碼思維大相徑庭。只用別人定義好的註解是搞不懂這些問題的,要想真正知道註解內部的祕密,要自己定義註解,然後在程序中獲取註解信息,拿到註解信息後,就可以爲我所用了。
下面我簡單演示下三類註解的用法:類註解、方法註解、字段(也稱之域)註解的定義與適用,並看看如何獲取註解的信息。

二、使用注意點

(1)自定義註解,注意註解的時空範圍,簡單說就是註解針對的目標(類、方法、字段),以及註解的時效(運行時、或者源碼中有效)。
(2)要獲取註解的信息,必須通過Java的反射技術來獲取Annotation對象,因爲你除此之外沒有別的獲取註解對象的方法。
(3)獲取了註解對象,就可以調用註解的方法來獲取相對應的值了。爲基礎框架所用。
(4)當然,註解也可以沒有定義成員,這樣註解就成了一個標記符號了。

三、代碼實戰:

(1)AnnotationInterfaceFIELD.java

package com.demo.annotation;

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Inherited
@Documented
public @interface AnnotationInterfaceFIELD {
	public String descriptionFIELD();
}
(2)AnnotationInterfaceMETHOD.java

package com.demo.annotation;

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
@Documented
public @interface AnnotationInterfaceMETHOD {
	public String descriptionMETHOD();
}
(3)AnnotationInterfaceTYPE.java
package com.demo.annotation;

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

//@Retention(value=RetentionPolicy.RUNTIME)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
//@Target({ElementType.FIELD, ElementType.METHOD})
@Inherited
@Documented
public @interface AnnotationInterfaceTYPE {
	String name() default "bob";
	int age() default 24; 
}
(4)AnnotationTestClass.java
package com.demo.annotation;

@AnnotationInterfaceTYPE(name="chy龍神的博客",age=24)
public class AnnotationTestClass {
	
	@AnnotationInterfaceFIELD(descriptionFIELD="annotation private field")
	private String privateField;
	
	@AnnotationInterfaceFIELD(descriptionFIELD="annotation protected field")
	protected String protectedField;
	
	@AnnotationInterfaceFIELD(descriptionFIELD="annotation public field")
	public String publicField;
	
	@AnnotationInterfaceMETHOD(descriptionMETHOD="annotation private method")
	public void privateMethod() { }
	
	@AnnotationInterfaceMETHOD(descriptionMETHOD="annotation protected method")
	public void protectedMethod() { }
	
	@AnnotationInterfaceMETHOD(descriptionMETHOD="annotation public method")
	public void publicMethod() { }
}
(5)AnnotationTestDemo

package com.demo.annotation;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class AnnotationTestDemo {

	public static void main(String[] args) {
		AnnotationTestClass cls = new AnnotationTestClass();
		try {
			Class annotationCls = Class.forName("com.demo.annotation.AnnotationInterfaceTYPE");
			if(cls.getClass().isAnnotationPresent(annotationCls)) {
				System.out.println("\nAnnotation Type=====================");
				AnnotationInterfaceTYPE annotationType = cls.getClass().getAnnotation(AnnotationInterfaceTYPE.class);
				System.out.println("annotationType.name = " + annotationType.name());
				System.out.println("annotationType.name = " + annotationType.age());
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		System.out.println("\nAnnotation Field====================");
		//getField只能獲取類的public字段
		Field[] fields = cls.getClass().getFields();
		System.out.println("1、getField"+"("+fields.length+")");
		dumpFields(fields);
		
		//getDeclaredField是可以獲取一個類的所有字段
		Field[] declardFields = cls.getClass().getDeclaredFields();
		System.out.println("\n2、getDeclaredField"+"("+declardFields.length+")");
		dumpFields(declardFields);
		
		try {
			Field mField = cls.getClass().getDeclaredField("publicField");
			AnnotationInterfaceFIELD mAnnotationField = mField.getAnnotation(AnnotationInterfaceFIELD.class);
			System.out.println(mAnnotationField.descriptionFIELD());
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		}
			
		System.out.println("\nAnnotation Method===================");
		Method[] methods = cls.getClass().getMethods();
		System.out.println("1、getMethod"+"("+methods.length+")");
		dumpMethods(methods);
		
		Method[] declardMethods = cls.getClass().getDeclaredMethods();
		System.out.println("\n2、getDeclaredMethod"+"("+declardMethods.length+")");
		dumpMethods(declardMethods);
		
		try {
			Method mMethod = cls.getClass().getDeclaredMethod("publicMethod");
			AnnotationInterfaceMETHOD mAnnotatMethod = mMethod.getAnnotation(AnnotationInterfaceMETHOD.class);
			System.out.println(mAnnotatMethod.descriptionMETHOD());
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
	}
	
	public static void dumpFields(Field[] fields) {
		for(int i=0;i<fields.length;i++) {
			System.out.println("("+i+")"+fields[i].getName());
		}
	}
	
	public static void dumpMethods(Method[] methods) {
		for(int i=0;i<methods.length;i++) {
			System.out.println("("+i+")"+methods[i].getName());
		}
	}
}

四、運行截圖:

補充:個人感覺其實對於“class的註解”與“添加基類的共有方法”無異。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章