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.javapackage 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.javapackage 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.javapackage 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)AnnotationTestDemopackage 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.javapackage 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.javapackage 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.javapackage 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)AnnotationTestDemopackage 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的註解”與“添加基類的共有方法”無異。