Annoation简介:
Java1.5新特性对元数据(Metadata)的支持,这种“元”数据称为注释(Annoation)。程序人员可以在不改变原有逻辑的情况下,在源文件中加入一些补充信息。
Annotation可以用来修饰类、属性、方法,java.lang.anntation.Annotation是Annotation最大的父接口,所有Annotation都必须实现此接口。
系统内建的Annoation:
在JDK1.5后,系统系统提供了内建的Annotation类型,用户可以直接使用:
@Overried:覆写的Annotation
@Deprecated:不建议使用的Annotation
@SuppressWarnings:压制安全警告的Annotation
这3个Annotation定义在java.lang包中,它们默认都实现了Annotation接口。
@Overried:一个类覆写了Object中的equals()
@Override publicboolean equals(Object obj) {} |
@Deprecated:sayHello()标记为过时的、不建议使用的方法
@SuppressWarnings:main()中调用了过时的sayHello(),编译时将会出现警告信息
publicclass AnnotationTest { @SuppressWarnings("deprecation") publicstaticvoid main(String[] args) { System. } @Deprecated publicstaticvoid System.out.println("hello world"); } } |
自定义Annotation:
自定义Annotation使用@interface进行定义,使用@interface就相当于继承了java.lang.annotation.Annotation接口。
public@interfaceMyAnnotation { } |
定义Annotation类时也可以在内部定义属性:
public@interfaceMyAnnotation { String name(); } |
测试自定义的MyAnnotation:
@MyAnnotation(name="李岩") publicclass MyAnnotationTest { }
|
定义多个属性,传递多个值:
public@interfaceMyAnnotation { String name(); int age(); String city(); } |
@MyAnnotation(name="李岩", age = 10, city = "BJ") publicclass MyAnnotationTest {} |
传递多个值也可使使用数组:
public@interfaceMyAnnotation { // String name(); // int age(); // String city(); String[] value(); } |
@MyAnnotation(value = { "李岩,李小岩,李大岩" }) publicclass MyAnnotationTest {} |
在使用Annotation类中定义多个属性,在使用时必须为所有属性赋值,如果没有为所有属性赋值,将无法通过编译。但可以为属性设置默认值。
public@interfaceMyAnnotation { String name() default"liyan"; int age() default 10; String city() default"BJ"; String[] value(); } |
使用枚举限制Annotation中属性的取值:
publicenum MyName { Lee,Rock,RockLee,RL; } |
public@interfaceMyAnnotation { MyName myName() default MyName.RL; |
Annotation的保存范围:
在Annotation中可以使用Retention定义的RetentionPolicy变量设置Annotation的保存范围,RetentionPolicy三种保存范围:
SOURCE:只保留在*.java源文件中,编译后不会保存在*.class文件中
CLASS:保留在*.java、*.class中,但不会加载到JVM中,如果Annotation声明时没有制定其范围,默认就是CLASS
RUNTIME:*.java、*.class、JVM中
@Override-SOURCE @Deprecated-RUNTIME @SuppresWarning-SOURCE
自定义Annotation设置为RUNTIME范围
@Retention(RetentionPolicy.RUNTIME) public@interfaceMyAnnotation { MyName myName() default MyName.RL; String name() default"liyan"; int age() default 10; String city() default"BJ"; String[] value() default {"A","B"}; String color() default"blue"; } |
Annotion结合反射:
通过反射取得Annotation:
@MyAnnotation(name = "李岩", age = 10, city = "BJ", value = { "李岩,李小岩,李大岩" }) publicclass MyAnnotationTest { publicstaticvoid main(String[] args) { // 通过反射取得MyAnnotationTest类 Class<?> clazz = Class.forName("rock.lee.enhance.MyAnnotationTest"); // 取得toString()方法 Method m = clazz.getMethod("toString", null); // 取得toString()上的全部Annotation Annotation[] anns = m.getAnnotations(); for (Annotation a : anns) System.out.println(a); }
@MyAnnotation(city = "SH",age = 15) @Deprecated @Override @SuppressWarnings("deprecation") public String returnnull; } } |
Deprecated、Override、SuppressWarnings只能取得Deprecated,还可以取得MyAnnotation,因为设置了@Retention(RetentionPolicy.RUNTIME)。
获得Annotation中属性的内容:
publicclass MyAnnotationTest { publicstaticvoid main(String[] args){ Class<?> clazz = Class.forName("rock.lee.enhance.MyAnnotationTest"); // 取得toString()方法 Method m = clazz.getMethod("toString", null); // 判断一个类是否使用Annotation if (m.isAnnotationPresent(MyAnnotation.class)) { // 声明自定义的Annotion对想,并获得自定义的Annotation MyAnnotation ma = m.getAnnotation(MyAnnotation.class); String name = ma.name(); int age = ma.age(); System.out.println(name + "-->" + age); } } @MyAnnotation(city = "SH", age = 15) @Deprecated @Override @SuppressWarnings("deprecation") public String returnnull; } } |