使用注解
`注解(Annotation)`是放在Java源码的类、方法、字段、参数前的一种标签。
注解本身对代码逻辑没有任何影响,如何使用注解由工具决定。
编译器可以使用的注解:
-
@Override
让编译器检查该方法是否正确实现了覆写 -
@Deprecated
告诉编译器,该方法被标记为“作废”,在其他地方引用将会出现警告 -
@SuppressWarnings
告诉编译器,在这个方法内部如果出现警告,编译器会忽略这些编译警告。public class Hello { @Override public String toString() { return "Hello"; } @Deprecated public void hello(String name) { System.out.println("name"); } @SuppressWarnings("unused") public void hello() { int n; //local variable n is not used } }
注解可以定义配置参数和默认值。
-
配置参数由注解类型定义
-
配置参数可以包括:
-
所有的基本类型
-
String
-
枚举
-
数组
-
-
配置参数必须是常量
public class Hello { int n=100; @Test(timeout=100) public void test() { System.out.println("Test"); } }
-
缺少某个配置参数将使用默认值
-
如果只写常量相当于省略了value参数
-
如果只写注解相当于全部使用默认
public class Hello { @Check(min=0,max=100,value=50) public int n; @Check(value=99) public int p; @Check(99) ///@Check(value=99) public int x; @Check public int y; }
定义注解
使用@interface
定义注解(Annotation)
-
注解的参数类似无参方法
-
可以设定一个默认值(推荐)
-
把最常用的参数值命名为value(推荐)
public @interface Report { int type() default 0; String level() default "info"; String value() default ""; }
使用元注解定义注解:
-
@Target
定义Annotation 可以被应用于源码的那些位置:-
类和接口 :ElementType.TYPE
-
字段:ElementType.FIELD
-
方法:ElementType.METHOD
-
构造方法:ElementType.CONSTRUCTOR
-
方法参数:ElementType.PARAMETER
@Target(ElementType.METHOD) public @interface Report { int type() default 0; String level() default "info"; String value() default ""; }
-
-
@Retention
定义Annotation的生命周期-
仅编译期:RetentionPolicy.SOURCE
-
仅class文件:RetentionPolicy.CLASS
-
运行期:RetentionPolicy.RUNTIME
-
如果
@Retention
不存在,则该Annotation默认为CLASS -
通常自定义的Annotation都是RUNTIME
@Retention(RetentionPolicy.RUNTIME) public @interface Report { int type() default 0; String level() default "info"; String value() default ""; }
-
-
@Repeatable
定义 Annotation是否可重复- JDK > 1.8
-
@Inherited
定义子类是否可以继承父类的Annotation- 仅针对
@Target
为Type类型的Annotation - 仅针对class的继承
- 对interface的继承无效
- 仅针对
定义Annotation的步骤:
-
用
@interface
定义注解 -
用元注解(meta annotation)配置注解
Target:必须设置
Retention:一般设置为RUNTIME
通常不必写@Inherited, @Repeatable等等 -
定义注解参数和默认值
处理注解
使用反射API读取Annotation:
-
Class.isAnnotationPresent(Class)
-
Field.isAnnotationPresent(Class)
-
Method.isAnnotationPresent(Class)
-
Constructor.isAnnotationPresent(Class)
Class cls = Person.class; //判断@Report是否存在 cls.isAnnotationPresent(Report.class);
-
Class.getAnnotation(Class)
-
Field.getAnnotation(Class)
-
Method.getAnnotation(Class)
-
Constructor.getAnnotation(Class)
Class cls = Person.class; cls.isAnnotationPresent(Report.class); Report report = cls.getAnnotation(Report.class); //如果不存在返回null int type = report.type(); String level = report.level();
-
getParameterAnnotations() //返回一个二位数组
可以通过工具处理注解来实现相应的功能:
-
对JavaBean的属性值按规则进行检查
-
JUnit会自动运行
@Test
标记的测试方法