深入理解Java注解的使用方法
注解是jdk1.5新增的特性.大家都知道,jdk1.5在java的发展史上有着划时代的意义.而注解的出现,在某种程度上颠覆了框架的设计.比如,spring在注解出现后,改善了原先五大组件的模式,增加了基于注解的实现方式.现在重点讲讲注解的使用.
元注解:
jdk1.5定义了4个元注解,元注解的作用是注解其他的注解.
1.@retention
2.@target
3.@documented
4.@inherited
@retention用于指明该注解存在的时机.参数有三个值可选:retentionpolicy.source,retentionpolicy.class,retentionpolicy.runtime可供选择.分别表示:源码中保留注解,字节码文件中保留注解,运行时保留注解.
@target用于指明注解能作用的范围.比如参数中设置为elementtype.type,表示作用于类和接口.如果你用来注解方法,则会发生编译错误.由此可见它的功能是通过编译器实现的.
@documented表明该注解在使用javadoc工具生成开发文档时,也会被纳入进去.
@inherited表明,某个位置使用该注解,那么在存在java继承关系的地方,该注解也能被继承过来.这个可能不好理解.下面的代码加以说明.
@retention(retentionpolicy.runtime) @target({elementtype.type,elementtype.method}) @inherited public @interface annoinherited { }
测试代码:
public class testannoinherated { public static void main(string[] args) { annotation[] annos=new goo().getclass().getannotations(); for(annotation a:annos){ system.out.println(a); } } } @annoinherited class foo{ } class goo extends foo{ }
控制台输出:
@test.annotation.annoinherited()
上例中goo前面并没有加注解@annoinherited,但是父类foo前面有,而@annoinherited加了元注解@inherited,所以foo能继承过来.
自定义注解:
自定义注解的实例如下.
package test.annotation; import java.lang.annotation.documented; import java.lang.annotation.elementtype; import java.lang.annotation.retention; import java.lang.annotation.retentionpolicy; import java.lang.annotation.target; @target(elementtype.type) @retention(retentionpolicy.runtime) @documented public @interface animalinfo { string shout() default ""; //能不能看门 boolean isguard() default true; }
测试代码:
public class testanimalinfo { public static void main(string[] args) { animal animal=new animal(); animalinfo info=animal.getclass().getannotation(animalinfo.class); if(info!=null){ annotation anno=info;//此处并没有报错.annotation是一个接口.info是一个注解.这是因为编译器会将注解编译成接口,并且继承了annotation system.out.println("annotation类信息:"+annotation.class); system.out.println("animalinfo类信息:"+animalinfo.class); class[] cs=animalinfo.class.getinterfaces(); for(class c:cs){ system.out.println(c); //animalinfo编译后就是一个接口,并且继承了annotation,这里得到了证实. } system.out.println("info对象的类信息:"+info.getclass()); if("wangwang".equals(info.shout())&&info.isguard()){ system.out.println("the animal is a dog"); }else if("miaomiao".equals(info.shout())&&!info.isguard()){ system.out.println("the animal is a cat"); }else{ system.out.println("the animal is not a dog or cat"); } }else{ system.out.println("it's not a animal"); } } } @animalinfo(shout="wangwang",isguard=true) class animal{ }
控制台输出:
annotation类信息:interface java.lang.annotation.annotation animalinfo类信息:interface test.annotation.animalinfo interface java.lang.annotation.annotation info对象的类信息:class com.sun.proxy.$proxy1 the animal is a dog
代码分析:从控制台可以看到.@animalinfo注解其实编译后就是接口,并且它继承了annnotation.而通过反射获得的注解实例,名字为$proxy1,是一个类的对象.可见,该注解实例是jvm通过动态代理技术生成的.这也揭示了注解特性的底层实现原理.关于注解的具体底层技术原理,这里不再详谈.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。