在java中我们可以自己定义注解,格式如下:
第一步,用@interface定义注解第二步,添加参数、默认值(最常用的参数定义为value)第三步,用元注解配置注解定义注解@Report
public @interface Report { int type() default 0;//注解的参数,类似于无参方法,default设置默认值 String level() default "info"; String value() default ""; }元注解:可以修饰其他注解的注解叫做元注解 java中已经定义了一些元注解,通常我们只需要使用而不需要去编写。
@Target:在定义注解时添加,它可以将注解定义在用于源码的那些位置: - 类或接口:ElementType.TYPE; - 字段:ElementType.FIELD; - 方法:ElementType.METHOD; - 构造方法:ElementType.CONSTRUCTOR; - 方法参数:ElementType.PARAMETER。
@Target(ElementType.METHOD)//定义注解@Report可用在方法中 public @interface Report { int type() default 0; String level() default "info"; String value() default ""; }@Retention:定义了注解的生命周期,若不定义则默认class阶段 - 仅编译期:RetentionPolicy.SOURCE; - 仅class文件:RetentionPolicy.CLASS; - 运行期:RetentionPolicy.RUNTIME。
@Retention(RetentionPolicy.RUNTIME) public @interface Report { int type() default 0; String level() default "info"; String value() default ""; }@Repeatable:可以定义注解(Annotation)是否可重复 最终注解可以如下:
@Report(type=1, level="debug") @Report(type=2, level="warning") public class Hello { }@Inherited:定义子类是否可以继承父类定义的注解。(只针对@Target为类或接口类型有效)
所有的注解都继承自java.lang.annotation.Annotation,因此,读取注解,需要使用反射API。 方法包括: 判断注解是否存在类、字段、方法或是构造方法中:
Class.isAnnotationPresent(Class) (类)Field.isAnnotationPresent(Class) (字段)Method.isAnnotationPresent(Class) (方法)Constructor.isAnnotationPresent(Class) (构造方法) 例如,判断@Report是否存在Person类中 Person.class.isAnnotationPresent(Report.class);利用反射读取注解值:
Class.getAnnotation(Class)Field.getAnnotation(Class)Method.getAnnotation(Class)Constructor.getAnnotation(Class) 例: // 获取Person定义的@Report注解: if (cls.isAnnotationPresent(Report.class)) { Report report = Person.class.getAnnotation(Report.class); } int type = report.type(); String level = report.level();利用反射读取注解可能会有空值返回因此,在获取值之前要先判断。
注解如何使用,由程序自己决定。 该注解定义一个字段的规则
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Range { int min() default 0; int max() default 255; } public class Person { @Range(min=1, max=20) public String name; @Range(max=10) public String city; }