自定义注解
1、annotation(注解)含义
annotation是Java提供的一种元程序中的元素关联任何信息和任何元数据(metadata)的途径和方法。
annotation是一个接口,程序可以通过反射来获取指定程序元素的annotion对象,然后通过annotation对象来获取注解里面的元数据。
annotation就像修饰符一样被使用,并应用于包、类 型、构造方法、方法、成员变量、参数、本地变量的声明中。这些信息被存储在annotation的“name=value”结构对中。
2、自定义注解
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。
@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。
方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。
(1)自定义注解格式:
/** * 自定义注解 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface 注解名 { 注解体 }
(2)参数设置
- 只能用public或default这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型;
- 参数成员只能用基本类型(byte,short,char,int,long,float,double,boolean八种基本数据类型)和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String;
- 如果只有一个参数成员,最好把参数名称设为"value",后加小括号。 例如:
/** * xxx注解 */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface xxx { String value() default ""; }
(3)注解元素的默认值
- 注解元素必须有确定的值,要么在定义注解的默认值中指定,要么在使用注解时指定,非基本类型的注解元素的值不可为null。
- 因此, 使用空字符串或0作为默认值是一种常用的做法。
(4)注解处理器类库(java.lang.reflect.AnnotatedElement)
注解元素使用Annotation接口来代表程序元素前面的注解,该接口是所有Annotation类型的父接口。
除此之外,Java在java.lang.reflect 包下新增了AnnotatedElement接口,该接口代表程序中可以接受注解的程序元素,该接口主要有如下几个实现类:
- Class:类定义
- Constructor:构造器定义
- Field:累的成员变量定义
- Method:类的方法定义
- Package:类的包定义
(5)访问annotation的信息
- 方法1:<T extends Annotation> T getAnnotation(Class<T> annotationClass): 返回该程序元素上存在的、指定类型的注解,如果该类型注解不存在,则返回null。
- 方法2:Annotation[] getAnnotations(): 返回该程序元素上存在的所有注解。
- 方法3:boolean isAnnotationPresent(Class<?extends Annotation> annotationClass): 判断该程序元素上是否包含指定类型的注解,存在则返回true,否则返回false.
- 方法4:Annotation[] getDeclaredAnnotations(): 返回直接存在于此元素上的所有注释。与此接口中的其他方法不同,该方法将忽略继承的注释。(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。
3、示例
自定义xxx注解-->编写注解解析器-->在某个类中使用注解-->注解测试
/** * 自定义球颜色注解 */ @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface BallColor { public enum MyColor { YELLOW,BLUE,GREEN,BLACK,RED,PINK } public MyColor ballColor() default MyColor.BLUE; }
/** * 自定义球类别注解 */ @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface BallType { String value() default "ball"; }
/** * 注解解析器 */ public class BallParser { public static void getBallInfo(Class<?> clazz){ String strBallColor = "球颜色:"; String strBallType = "球类别:"; //得到所有方法包括私有方法,返回一个数组 Field[] fields = clazz.getDeclaredFields(); for (Field field:fields) { //判断该程序元素上是否包含指定类型的注解 if (field.isAnnotationPresent(BallColor.class)) { BallColor ballColor = (BallColor)field.getAnnotation(BallColor.class); strBallColor = strBallColor + ballColor.ballColor().toString(); System.out.println(strBallColor); } if (field.isAnnotationPresent(BallType.class)) { BallType ballType = (BallType)field.getAnnotation(BallType.class); strBallType = strBallType + ballType.value(); System.out.println(strBallType); } }
/** * 在类中使用注解 */ public class Ball { @BallType private String ballType; @BallColor(ballColor=MyColor.GREEN) private String ballColor; public String getBallType() { return ballType; } public void setBallType(String ballType) { this.ballType = ballType; } public String getBallColor() { return ballColor; } public void setBallColor(String ballColor) { this.ballColor = ballColor; } }
/** * 注解测试 */ public class BallTest { public static void main(String[] args){ BallParser.getBallInfo(Ball.class); } }