前言
上一篇对注解是什么和其原理做了简单的介绍(传送门),本篇手写实现一个简单的注解示例。
注解的使用场景
对注解有了一定的熟悉之后,那么注解到底有什么用呢?
java官网定义:
注解是一系列元数据,它提供数据用来解释程序代码,但是注解并非是所解释的代码本身的一部分。注解对于代码的运行效果没有直接影响。
注解有许多用处,主要如下:
- 提供信息给编译器: 编译器可以利用注解来探测错误和警告信息
- 编译阶段时的处理: 软件工具可以用来利用注解信息来生成代码、Html文档或者做其它相应处理。
- 运行时的处理: 某些注解可以在程序运行的时候接受代码的提取
注解并非是所解释的代码本身的一部分,即注解起的作用类似于标签,不改变其本身,只是针对特定事物的功能。当开发者使用了Annotation 修饰了类、方法、Field 等成员之后,这些 Annotation 不会自己生效,必须由开发者提供相应的代码来提取并处理 Annotation 信息。这些处理提取和处理 Annotation 的代码统称为 APT(Annotation Processing Tool)。
手写注解
需求: 一个计算类具有加减乘除方法,当执行方法时要检查其有没有使程序产生异常,如果有则将异常信息显示。
注解类
@Retention(RetentionPolicy.RUNTIME)
public @interface Check {
}
计算类
计算类(Numeration )定义加减乘除,四个方法,其中除法除数为0,此处会有异常发生。
public class Numeration {
//加法
@Check
public void add() {
System.out.println("1+1=" + 1 + 1);
}
//减法
@Check
public void subtract() {
System.out.println("1-1=" + (1 - 1));
}
//乘法
@Check
public void multiply() {
System.out.println("1*2=" + (1 *2));
}
//除法
@Check
public void divide() {
System.out.println("1/0=" + 1 /0);
}
}
测试类
public class testAnn {
public static void main(String[] args) {
//实例化计算类
Numeration numeration = new Numeration();
//使用反射获取到计算类的方法数组
Method[] methods = numeration.getClass().getDeclaredMethods();
//使用StringBuilder来记录日志
StringBuilder sb = new StringBuilder();
//error用来记录出错次数
AtomicInteger error = new AtomicInteger();
//使用lambda循环遍历methods
Arrays.asList(methods).forEach((
method -> {
//检测方法上是否有@Check注解
if (method.isAnnotationPresent(Check.class)) {
try {
//设置方法的访问权限为true
method.setAccessible(true);
//调用numeration中方法
method.invoke(numeration, null);
} catch (IllegalAccessException e) {
// e.printStackTrace();
} catch (InvocationTargetException e) {
// e.printStackTrace();
//当调用出现异常时,使用StringBuilder收集数据
error.getAndIncrement();
sb.append("类名为")
.append(method.getClass())
.append(" "+"原因为:")
.append(e.getCause().getMessage());
}
}
}
));
sb.append(" "+"错误次数为:")
.append(error);
System.out.println(sb);
}
}
输出结果
1+1=11
1*2=2
1-1=0
类名为class java.lang.reflect.Method 原因为:/ by zero 错误次数为:1
一个简单的自定义注解实现~