什么是注解
百度是这样说的:从JDK5开始,Java增加对元数据的支持,也就是注解,注解与注释是有一定区别的,可以把注解理解为代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通过注解开发人员可以在不改变原有代码和逻辑的情况下在源代码中嵌入补充信息 。
java中注解作用分类
- 编写文档:通过代码里表示的注解生成文档【生成doc文档】
- 代码分析:通过代码里表示的注解对代码进行分析【使用反射】
- 编译检查:通过代码里表示的注解让编译器能够实现基本的编译检查【Override】
JDK中预定义的一些注解
@Override
:检测呗改注解标注的方法是否是继承自父类(接口)的
@Deprecated
:
@SuppressWarnings
:压制警告,消除所有警告
元注解:用于描述注解的注解
ElementType取值(枚举):
- TYPE:可以作用于类上
- METHOD:可以作用于方法上
- FIELD:可以作用于成员变量上
@Retention
:描述注解被保留的阶段
@Retention(RetentionPolicy.RUNTIME)
:当前被描述的注解,会被保留到class字节码文件中,并被JVM读取到(常用)
@Documented
:描述注解是否被抽取到api文档中
@Inherited
:描述注解是否被子类继承
自定义注解
格式
1 2
| 元注解() public @interface 注解名称{}
|
本质:注解本质上就是一个接口,该接口默认继承Annotation接口
1
| pulic interface MaAnno extends java.lang.annotation.Annotation
|
注解的属性
注解的属性:接口中的抽象方法
- 属性的返回值类型
- 基本数据类型
- 定义的属性,在使用时需要给属性赋值
- 如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不进行属性的赋值
- 如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义值即可
在程序使用(解析)注解
在程序使用(解析)注解:获取注解中定义的属性值
- 获取注解定义的位置的对象(Class,Method,Field)
- 获取指定的注解
- 调用注解中的抽象方法获取配置的属性值
自定义注解小案例
需求:使用注解的方式,检测以下方法是否存在bug
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Calculator { public void add(){ System.out.println("1 + 0 =" + (1 + 0)); } public void sub(){ System.out.println("1 - 0 =" + (1 - 0)); } public void mul(){ System.out.println("1 * 0 =" + (1 * 0)); } public void div(){ System.out.println("1 / 0 =" + (1 / 0)); } }
|
定义注解类Check
1 2 3 4 5 6 7 8 9
| import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Check { }
|
在Calculate类的方法上添加@Check
注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Check public void add(){ System.out.println("1 + 0 =" + (1 + 0)); } @Check public void sub(){ System.out.println("1 - 0 =" + (1 - 0)); } @Check public void mul(){ System.out.println("1 * 0 =" + (1 * 0)); } @Check public void div(){ System.out.println("1 / 0 =" + (1 / 0)); }
|
编写解析类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| public class TestCheck {
public static void main(String[] args) throws IOException { Calculator c = new Calculator(); Class<? extends Calculator> cls = c.getClass(); Method[] methods = cls.getMethods(); int number = 0; BufferedWriter bw = new BufferedWriter(new FileWriter("bug.txt"));
for (Method method : methods) { if (method.isAnnotationPresent(Check.class)) { try { method.invoke(c); } catch (Exception e) { number++; bw.write(method.getName() + "方法出异常了"); bw.newLine(); bw.write("异常的名称:" + e.getCause().getClass().getSimpleName()); bw.newLine(); bw.write("异常的原因:" + e.getCause().getMessage()); bw.newLine(); bw.write("----------------------------------"); bw.newLine(); } } } bw.write("本次测试一共出现" + number + "次异常"); bw.flush(); bw.close(); } }
|
结果

生成了bug.tex文件记录异常信息

总结
- 以后大多数时候,我们会使用注解,而不是自定义注解
- 注解给谁用
- 注解不是程序的一部分,可以理解为注解就是一个标签