注解就是一个标识符,用来标识身份、处理规则等。注解是出现可以代替XML配置文件,使程序更加清晰明了。注解也是框架配置的发展方向,对于Spring而言,虽然有人反对使用注解对Spring进行配置,说这是违背了Spring的IoC的理念,其实不然。使用注解将Java类注解为配置文件和使用XML是一样的,还可以减少配置文件,并且更加自由化的定义bean的初始化过程。
注解是一门比较简单却很实用的技术,定义注解使用@interface关键字:
1 public @interface MyAnnotation { 2 3 }
在注解类的头上使用注解@Retention可以配置注解生效时间
-- RetentionPolicy.RUNTIME 运行时,即class文件载入内存处理为字节码以后
-- RetentionPolicy.SOURCE 源文件时,即在.java文件状态时生效
-- RetentionPolicy.CLASS 类文件时,即在.class文件状态时生效
通常使用RUNTIME时间范围。
在注解类头上使用注解@Target可以配置注解可以运用在什么位置
-- ElementType.TYPE 类头上
-- ElementType.METHOD 方法头上
-- ElementType.FIELD 属性头上
-- ElementType.PACKAGE 包头上
-- ElementType.ANNOTATION 注解头上
-- ...(其他不常用)
1 @Retention(RetentionPolicy.RUNTIME) 2 @Target({ElementType.TYPE, ElementType.METHOD}) 3 public @interface MyAnnotation { 4 5 }
PS:为@Target指定多个可用范围时传入数组参数即可。
为注解增加属性类似于写一个抽象方法,在使用注解时,以属性的方式使用,使用default来指定注解属性的默认值
1 @Retention(RetentionPolicy.RUNTIME) 2 @Target(ElementType.TYPE) 3 public @interface MyAnnotation { 4 5 String name() default "Bob"; //指定了默认值的属性在使用注解时可以不配置 6 7 String value(); //将属性名声明为value,若使用注解时只需要配置value属性,可以直接填入值,而不需要使用赋值操作 8 9 int[] iArr(); //注解属性的类型可以为数组、枚举、注解 10 }
为了直观表名上述属性的配置,示例如下:
1 @MyAnnotation(value="jason", iArr={1,2,3}) 2 public class User { 3 4 }
在使用注解时使用 属性名= 属性值的格式为注解的属性赋值,在注解类中使用default声明了默认值的属性可以不用配置,系统将自动调用其默认值。特别的:
如果我们将iArr属性也设置了默认值,那么在使用注解时我们只需要配置value属性的值即可,如下:
1 @MyAnnotation("jason") 2 public class User { 3 4 }
当注解中的某个属性声明为value这个名称时,在配置时可以直接传入属性值,而不需要使用属性名= 属性值的格式。前提是除了value以前的其他属性都设置了default值,不需要显示配置的情况下。
光有一个注解是没有用的,注解必须要配合反射使用,才能发挥作用:
1 public class Test { 2 3 public void main(String[] args) { 4 Class<User> clazz = User.class; 5 //判断这个类的头上是否存在MyAnnotation这个注解 6 if (clazz.isAnnotationPresent(MyAnnotation.class)) { 7 //获得注解 8 MyAnnotation anno = clazz.getAnnotation(MyAnnotation.class); 9 anno.value(); //获得配置的属性值 10 } 11 } 12 13 }
通过使用isAnnotationPresent(Class<? extends Annotation> clazz)方法来判断某个注解是否存在,然后进行不同的业务操作,这就是注解配合反射的使用。