【受 http://www.tmser.com/?post=34&page=1 這篇文章啓發,本身寫了一遍,代碼微微有出入,方便本身理解。】html
1.定義兩個註解器(annotation):testA testB。java
public class testAnnotation { @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface TestA { String name(); int id() default 0; Class gid(); } @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface TestB { String Bname(); int Bid() default 10; Class Bgid(); } }
2.寫一個被註解類:UserAnnotation,用來作被註解(對其Type、Method、Field、Constructor、Method Parameter等各個子元素分別賦予額外的參數)的對象。框架
@TestA(name="type",gid=Long.class) @TestB(Bname="typeB",Bgid=Integer.class)//類成員註解 public class UserAnnotation { @TestA(name="param",id=1,gid=Long.class) @TestB(Bname="paramB",Bid=2,Bgid=Integer.class)//類成員註解 private Integer age; @TestA (name="construct",id=2,gid=Long.class) @TestB (Bname="construct",Bid=2,Bgid=Long.class)//構造方法註解 public UserAnnotation(){ } @TestA(name="public method",id=3,gid=Long.class) //類方法註解 public void a(){ Map m = new HashMap(0); } @TestA(name="protected method",id=4,gid=Long.class) //類方法註解 protected void b(){ Map m = new HashMap(0); } @TestA(name="private method",id=5,gid=Long.class) //類方法註解 private void c(){ Map m = new HashMap(0); } public void d(@TestA(name="paramA",id=7,gid=Double.class)Integer paramA, @TestB(Bname="paramB",Bid=8,Bgid=Boolean.class)Integer paramB){ } }
3.寫一個工具類:ParseAnnotation,用來演示從被註解類獲取註解參數的方法和過程,包含一個main函數。函數
public class ParseAnnotation { //引入兩個註解類,爲了演示對同一個ElementType的多重註解 static final Class[] classArr = {TestA.class,TestB.class}; //獲取ElementType.Type(整個類)的註解參數 public static void parseTypeAnnotation() throws ClassNotFoundException { final Class clazz = Class.forName("test.UserAnnotation"); for(Class c : classArr){ boolean hasAnnotation = clazz.isAnnotationPresent(c); if (hasAnnotation) { Annotation annotation = clazz.getAnnotation(c); System.out.println("Class = "+clazz+" ; Class Annotation="+c.cast(annotation).toString()); } } } //獲取ElementType.CONSTRUCTOR的註解參數 public static void parseConstructorAnnotation(){ System.out.println(""); Constructor[] constructors = UserAnnotation.class.getConstructors(); for (Constructor constructor : constructors) { for(Class c : classArr){ boolean hasAnnotation = constructor.isAnnotationPresent(c); if (hasAnnotation) { Annotation annotation = constructor.getAnnotation(c); System.out.println("Constructor = " + constructor.getName() + " ; Constructor Annotation=" + c.cast(annotation).toString()); } } } } //獲取ElementType.FIELD的註解參數 public static void parseFieldAnnotation(){ System.out.println(""); Field[] fields = UserAnnotation.class.getDeclaredFields(); for (Field field : fields) { boolean hasAnnotation = field.isAnnotationPresent(TestA.class); if (hasAnnotation) { TestA annotation =(TestA) field.getAnnotation(TestA.class); System.out.println("Field = " + field.getName() + " ; Field Annotation: id = " + annotation.id() + " ; description = " + annotation.name() + "; gid= "+annotation.gid()); } } } //獲取ElementType.METHOD的註解參數 public static void parseMethodAnnotation(){ System.out.println(""); Method[] methods = UserAnnotation.class.getDeclaredMethods(); for (Method method : methods){ for(Class c : classArr){ boolean hasAnnotation = method.isAnnotationPresent(c); if (hasAnnotation) { Annotation annotation = method.getAnnotation(c); System.out.println("Method = " + method.getName() + " ; Method Annotations=" + c.cast(annotation).toString()); } } } } //獲取ElementType.PARAMETER的註解參數 public static void parseParameterAnnotation(){ System.out.println(""); Method[] methods = UserAnnotation.class.getDeclaredMethods(); for (Method method : methods) { Parameter[] params = method.getParameters(); for(Parameter param : params){ for(Class c : classArr){ boolean hasAnnotation = param.isAnnotationPresent(c); if (hasAnnotation) { Annotation[] as = param.getAnnotations(); for(Annotation a : as){ System.out.println("Method Parameter = " + method.getName() +"."+param.getName()+" ; Parameter Annotation="+c.cast(a).toString()); } } } } } /*Annotation[][] an = method.getParameterAnnotations(); if(an.length != 0){ for(Annotation[] as : an){ for(Annotation a : as){ TestB testB = (TestB)a; System.out.println("method = " + method.getName() +" ; Declared parameter count with annotations: "+an.length +" ; Declared annotation count with one parameter: "+as.length+ " ; Parameter Annotations: id = " + testB.id() + " ; description = " + testB.name() + "; gid= "+testB.gid()); System.out.println(""); } } }*/ } public static void main(String[] args) throws ClassNotFoundException { parseTypeAnnotation(); parseConstructorAnnotation(); parseFieldAnnotation(); parseMethodAnnotation(); parseParameterAnnotation(); } }
4.運行結果:工具
Class = class test.UserAnnotation ; Class Annotation=@test.testAnnotation$TestA(id=0, name=type, gid=class java.lang.Long) Class = class test.UserAnnotation ; Class Annotation=@test.testAnnotation$TestB(Bid=10, Bname=typeB, Bgid=class java.lang.Integer) Constructor = test.UserAnnotation ; Constructor Annotation=@test.testAnnotation$TestA(id=2, name=construct, gid=class java.lang.Long) Constructor = test.UserAnnotation ; Constructor Annotation=@test.testAnnotation$TestB(Bid=2, Bname=construct, Bgid=class java.lang.Long) Field = age ; Field Annotation: id = 1 ; description = param; gid= class java.lang.Long Method = c ; Method Annotations=@test.testAnnotation$TestA(id=5, name=private method, gid=class java.lang.Long) Method = a ; Method Annotations=@test.testAnnotation$TestA(id=3, name=public method, gid=class java.lang.Long) Method = b ; Method Annotations=@test.testAnnotation$TestA(id=4, name=protected method, gid=class java.lang.Long) Method Parameter = d.arg0 ; Parameter Annotation=@test.testAnnotation$TestA(id=7, name=paramA, gid=class java.lang.Double) Method Parameter = d.arg1 ; Parameter Annotation=@test.testAnnotation$TestB(Bid=8, Bname=paramB, Bgid=class java.lang.Boolean)
5.關於全部的ElementType和RetentionPolicy,之後再研究。post
6.關於annotation的做用,網上有不少總結,大概就是框架中(吧?)我目前有感覺註解的方便就是在用Spring(用來聲明、鏈接bean和將其注入的位置等)和SpringMVC(參數綁定、聲明類型並處理response等)的註解方式時,固然還有AOP。spa
謝相關幾篇帖子:.net
http://www.tmser.com/?post=34&page=1code
http://blog.csdn.net/liuwenbo0920/article/details/7290586/htm
http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html
http://www.cnblogs.com/peida/archive/2013/04/26/3038503.html
http://ljz0898.iteye.com/blog/1290742