java自定义注解和使用

前言

上一篇对注解是什么和其原理做了简单的介绍(传送门),本篇手写实现一个简单的注解示例。

注解的使用场景

对注解有了一定的熟悉之后,那么注解到底有什么用呢?

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

一个简单的自定义注解实现~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章