一、擷取類上的註解
Java擷取類上的註解有下面3個方法: Class.getAnnotations() 擷取所有的註解,包括自己聲明的以及繼承的 Class.getAnnotation(Class< A > annotationClass) 擷取指定的註解,該註解可以是自己聲明的,也可以是繼承的 Class.getDeclaredAnnotations() 擷取自己聲明的註解
下面,我們來示範一下3個方法的使用。
首先,我們定義兩個註解ParentAnnotation、SubAnnotation
@Retention(RetentionPolicy.RUNTIME)@Target(value={ElementType.TYPE})@Documented@Inherited //可以繼承public @interface ParentAnnotation {}@Target(value={ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface SubAnnotation {}
接下來,我們定義兩個類,Parent、Sub,分別標註ParentAnnotation 註解和SubAnnotation註解
@ParentAnnotationpublic class Parent {}@SubAnnotationpublic class Sub extends Parent{}
一切準備OK後,就開始測試了。
public class AnnotationTest { public static void main(String[] args) { Annotation[] allAnnos = Sub.class.getAnnotations(); Annotation[] deAnnos = Sub.class.getDeclaredAnnotations(); Annotation subAnnotation = Sub.class.getAnnotation(SubAnnotation.class); Annotation parentAnnotation = Sub.class.getAnnotation(ParentAnnotation.class); printAnnotation("all",allAnnos); printAnnotation("declare",deAnnos); printAnnotation("sub",subAnnotation); printAnnotation("parent",parentAnnotation); } private static void printAnnotation(String msg,Annotation... annotations){ System.out.println("=============="+msg+"======================"); if(annotations == null){ System.out.println("Annotation is null"); } for (Annotation annotation : annotations) { System.out.println(annotation); } System.out.println(); }}執行結果:==============all======================@com.ghs.test.annotation.ParentAnnotation()@com.ghs.test.annotation.SubAnnotation()==============declare======================@com.ghs.test.annotation.SubAnnotation()==============sub======================@com.ghs.test.annotation.SubAnnotation()==============parent======================@com.ghs.test.annotation.ParentAnnotation()
嘗試著將ParentAnnotation中的@Inherited去掉,結果如下:
==============all======================@com.ghs.test.annotation.SubAnnotation()==============declare======================@com.ghs.test.annotation.SubAnnotation()==============sub======================@com.ghs.test.annotation.SubAnnotation()==============parent======================null
再試著將Sub類中的SubAnnotation去掉,結果如下:
==============all====================================declare====================================sub======================null==============parent======================null
經過幾番小小的測試,我們基本上可以得出下面幾條結論: 註解只有標註了@Inherited才能被子類繼承 當某個類沒有標註任何註解時,getAnnotations()和getDeclaredAnnotations()返回空數組 當某個註解查詢不到時,getAnnotation(Class< A > annotationType)方法返回null 二、擷取方法上的註解
修改上面的ParentAnnotation與SubAnnotation,使其可以標註在方法上
@Target(value={ElementType.TYPE, ElementType.METHOD})
在Sub、Parent中分別添加一個test()方法,如下:
@ParentAnnotationpublic class Parent { @ParentAnnotation public void test(){ }}@SubAnnotationpublic class Sub extends Parent{ @SubAnnotation public void test(){ }}
一切準備就緒,就可以進行測試了。
private static void testMethodAnnotation() { Method[] methods = Sub.class.getMethods(); for (Method method : methods) { if(method.getName().equals("test")){ Annotation[] allMAnnos = method.getAnnotations(); Annotation[] deMAnnos = method.getDeclaredAnnotations(); Annotation subMAnno = method.getAnnotation(SubAnnotation.class); Annotation parentMAnno = method.getAnnotation(ParentAnnotation.class); printAnnotation("allMAnnos",allMAnnos); printAnnotation("deMAnnos",deMAnnos); printAnnotation("subMAnno",subMAnno); printAnnotation("parentMAnno",parentMAnno); } }}
執行結果如下:
==============allMAnnos======================@com.ghs.test.annotation.SubAnnotation()==============deMAnnos======================@com.ghs.test.annotation.SubAnnotation()==============subMAnno======================@com.ghs.test.annotation.SubAnnotation()==============parentMAnno======================null
嘗試著刪除Sub中的test方法,再次進行測試,結果如下:
==============allMAnnos======================@com.ghs.test.annotation.ParentAnnotation()==============deMAnnos======================@com.ghs.test.annotation.ParentAnnotation()==============subMAnno======================null==============parentMAnno======================@com.ghs.test.annotation.ParentAnnotation()
經過兩輪測試,可以得出以下結論: 子類重寫的方法,註解無法被繼承 針對方法而言,getAnnotations()與getDeclaredAnnotations()返回的結果似乎永遠都是一樣的。
附:針對此結論,如有不同的想法,還望不吝賜教 三、擷取屬性上的註解
修改上面的ParentAnnotation與SubAnnotation,使其可以標註在屬性上
@Target(value={ElementType.TYPE, ElementType.METHOD,ElementTypeFIELD})
在Sub、Parent中分別添加一個name屬性,如下:
@ParentAnnotationpublic class Parent { @ParentAnnotation public String name; @ParentAnnotation public void test(){ }}@SubAnnotationpublic class Sub extends Parent{ @SubAnnotation public String name; @SubAnnotation public void test(){ }}
下面開始測試:
private static void testFieldAnnotation() { Field[] fields = Sub.class.getFields(); for (Field field : fields) { Annotation[] allFAnnos= field.getAnnotations(); Annotation[] deFAnnos = field.getDeclaredAnnotations(); Annotation subFAnno = field.getAnnotation(SubAnnotation.class); Annotation parentFAnno = field.getAnnotation(ParentAnnotation.class); printAnnotation("allFAnnos",allFAnnos); printAnnotation("deFAnnos",deFAnnos); printAnnotation("subFAnno",subFAnno); printAnnotation("parentFAnno",parentFAnno); System.out.println("**************************************************\n"); }}
執行結果如下:
==============allFAnnos======================@com.ghs.test.annotation.SubAnnotation()==============deFAnnos======================@com.ghs.test.annotation.SubAnnotation()==============subFAnno======================@com.ghs.test.annotation.SubAnnotation()==============parentFAnno======================null**************************************************==============allFAnnos======================@com.ghs.test.annotation.ParentAnnotation()==============deFAnnos======================@com.ghs.test.annotation.ParentAnnotation()==============subFAnno======================null==============parentFAnno======================@com.ghs.test.annotation.ParentAnnotation()**************************************************
經過測試,我們可以得出下面的幾個結論: 父類的屬性和子類的屬性互補幹涉 針對屬性而言,getAnnotations()與getDeclaredAnnotations()方法返回的結果似乎都是一樣的
附:針對此結論,如有不同的想法,還望不吝賜教