java Annotation注解
一、是什么java注释?
java sdk从jsee5开始添加了Annotation功能,其主要是为包、类 型、构造方法、方法、成员变量、参数、本地变量提供注释功能。Annotation的添加对java代码的正常执行不会产生任何影响,只是起到一个注解的作用。Annotation定义的信息只能在程序运行时通过反射机制被访问。
Annotation的使用场合,从我个人的应用范围内主要涉及到如下几点:
(1)可以标注一些变量的特殊状态,比如不能为空;
(2)可以再导出或者显示某些内容时,只显示或导出带有某种特殊标注的字段;
使用中就用到了以上两点,有使用过的朋友可以列出更多的使用的场合,共同学习。
二、java 标准的注释有哪些?
@Deprecated :被@Deprecated标注的对象class, method等被注明为不推荐使用(已过时)。使用被 Deprecated注释的方法,编译器会 提示方法过时警告(”Warring”),当程序仍然能正常运行。当某个方法已经有新的替代方法或者不再推荐使用时,为了兼容以前程序的正常运行,可以再方法头部加上该注解,以提示用户该方法已过期。
@Override :注明对象method重载了父类的方法。一方面表示了该方法是重载父类的方法,另一方面用于检查该方法的名称拼写是否正确。(仅用于方法)
@SuppressWarnings:单一注释,可以通过数组提供变量,变量值指明要阻止的特定类型警告(忽略某些警告)。数组中的变量指明要阻止的警告@SuppressWarnings(value={”unchecked”,”fallthrough”}))
@Target :target说明了annotation所修饰的对象范围:annotation可被用于packages、 types(类、接口、枚举、annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch 参数)。在annotation类型的声明中使用了target可更加明晰其修饰的目标。
@Retention :定义annotation的生命周期。
三、java标准注释的使用
@Deprecated的使用
(1)包含被@Deprecated注释的类
1 public class DeprecatedTest { 2 /** 3 * 过期注解的使用 4 * 定义如下: 5 * @Documented 6 * @Retention(RetentionPolicy.RUNTIME)// 7 * public @interface Deprecated { 8 * } 9 * 如果在某方法上加了@Deprecated注解,则该方法名称会被划上中划线 10 */ 11 @Deprecated 12 public void iamOld(){ 13 System.out.println("我已经过期了!"); 14 } 15 }
(2) 调用方法
1 public class StandardTest { 2 3 public static void main(String args[]){ 4 5 //带有@Deprecated注解方法的调用(出现“The method iamOld() from the type DeprecatedTest is deprecated”提示) 6 new DeprecatedTest().iamOld(); 7 8 } 9 }
@ Override的使用
(1)父类
1 public class OverrideParent { 2 public void override(){ 3 System.out.println("我在子类中被重写!!"); 4 } 5 }
(2)子类
1 public class OverrideTest extends OverrideParent { 2 3 public static void main(String[] args) { 4 new OverrideTest().override(); 5 } 6 @Override 7 public void override(){ 8 System.out.println("我重写了父类的override方法!"); 9 } 10 11 }
该注解对于不同的版本的使用也是有点区别的,请参见:JAVA中 @Override 的作用(1.5和1.6的区别)
@Target的使用
sdk中target的定义如下:
1 @Documented 2 @Retention(RetentionPolicy.RUNTIME) 3 @Target(ElementType.ANNOTATION_TYPE) 4 public @interface Target { 5 ElementType[] value(); 6 }
从target的定义中我们可以看到,target中定义了一个ElementType枚举类型的一个属性,该属性用于指示注释所能使用的范围,ElementType的定义如下:
1 public enum ElementType { 2 /** 用于类、接口(包含注解)、枚举的定义 (Class, interface (including annotation type), or enum declaration) */ 3 TYPE, 4 5 /** 字段包括枚举常量 (Field declaration (includes enum constants) )*/ 6 FIELD, 7 8 /** 方法的声明(Method declaration) */ 9 METHOD, 10 11 /** 参数声明(Parameter declaration) */ 12 PARAMETER, 13 14 /** 构造方法的声明 (Constructor declaration) */ 15 CONSTRUCTOR, 16 17 /** 本地变量的声明 (Local variable declaration) */ 18 LOCAL_VARIABLE, 19 20 /** 注解类型的声明 (Annotation type declaration) */ 21 ANNOTATION_TYPE, 22 23 /** 包的声明 ( Package declaration) */ 24 PACKAGE 25 }
该注解在定义其他注解时可以没有,若没有说明在使用时没有任何限制。
使用事例如下:
(1)定义基于类的注解
1 @Documented 2 @Retention(RetentionPolicy.RUNTIME) 3 @Target(ElementType.TYPE) 4 public @interface ClassAnno {}
(2)基于字段的注解
1 @Documented 2 @Retention(RetentionPolicy.RUNTIME) 3 @Target(ElementType.FIELD) 4 public @interface MenuAnno {}
(3)基于方法的注解
1 @Documented 2 @Retention(RetentionPolicy.RUNTIME) 3 @Target(ElementType. METHOD ) 4 public @interface MethodAnno {}
(4)基于参数声明的注解
1 @Documented 2 @Retention(RetentionPolicy.RUNTIME) 3 @Target(ElementType. PARAMETER ) 4 public @interface ParamAnno {}
(5)基于构造方法的注解
1 @Documented 2 @Retention(RetentionPolicy.RUNTIME) 3 @Target(ElementType. CONSTRUCTOR ) 4 public @interface ConstructorAnno {}
(6) 基于本地变量的注解
1 @Documented 2 @Retention(RetentionPolicy.RUNTIME) 3 @Target(ElementType. LOCAL_VARIABLE ) 4 public @interface LocalParamAnno {}
(7)基于注释的注解
1 @Documented 2 @Retention(RetentionPolicy.RUNTIME) 3 @Target(ElementType. ANNOTATION_TYPE ) 4 public @interface AnnoTypeAnno {}
(8) 基于包的注解
1 @Documented 2 @Retention(RetentionPolicy.RUNTIME) 3 @Target(ElementType. PACKAGE ) 4 public @interface PackageAnno {}
@Retention的使用
指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS。
Retention的定义如下:
1 @Documented 2 @Retention(value=RUNTIME) 3 @Target(value=ANNOTATION_TYPE) 4 public @interface Retention{ 5 RetentionPolicy value(); 6 }
同样Retention也只有一个枚举类型的属性,其定义如下:
1 public enum RetentionPolicy { 2 /** 3 * 编译器要丢弃的注释(只在源文件中存在)。 4 * Annotations are to be discarded by the compiler. 5 */ 6 SOURCE, 7 8 /** 9 * 编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。这是默认值。 10 * Annotations are to be recorded in the class file by the compiler 11 * but need not be retained by the VM at run time. This is the default 12 * behavior. 13 */ 14 CLASS, 15 16 /** 17 * 编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。 18 * Annotations are to be recorded in the class file by the compiler and 19 * retained by the VM at run time, so they may be read reflectively. 20 * 21 * @see java.lang.reflect.AnnotatedElement 22 */ 23 RUNTIME 24 }
注意:只有将 RetentionPolicy 设置为class,在反射时才能获取到给指定注解所设定的值!
以下内容摘自:http://www.blogjava.net/hao446tian/archive/2011/10/25/361960.html
@Documented:是一个标记注释,表示注释应该出现在类的javadoc中,因为在默认情况下注释时不包括在javadoc中的。
所以如果花费了大量的时间定义一个注释类型,并想描述注释类型的作用,可以使用它。
注意他与@Retention(RetentionPolicy.RUNTIME)配合使用,因为只有将注释保留在编译后的类文件中由虚拟机加载,
然后javadoc才能将其抽取出来添加至javadoc中。
@Inherited:将注释同样继承至使用了该注释类型的方法中(表达有点问题,就是如果一个方法使用了的注释用了@inherited, 那么其子类的该方法同样继承了该注释)
注意事项:
1.所有的Annotation自动继承java.lang.annotation接口
2.自定义注释的成员变量访问类型只能是public、default;(所有的都能访问,源作者没用到函数:getDeclaredFields而已)
3.成员变量的只能使用基本类型(byte、short、int、char、long、double、float、boolean和String、Enum、Class、annotations以及该类型的数据)(没有限制,大家可以修改测试一下,就清楚)
4.如果只有一个成员变量,最好将参数名称设为value,赋值时不用制定名称而直接赋值
5.在实际应用中,还可以使用注释读取和设置Bean中的变量。
参考网址:
(2) http://www.blogjava.net/hao446tian/archive/2011/10/25/361960.html