【受 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