Java注解Annotation

2021-12-04  本文已影响0人  Alse

注解

概念:说明程序的,给计算机看的
定义:从JDK5开始,Java增加对元数据的支持,也就是注解,注解与注释是有一定区别的,可以把注解理解为代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通过注解开发人员可以在不改变原有代码和逻辑的情况下在源代码中嵌入补充信息。

作用分类:

1、编写文档:通过代码里标识的元数据生成文档【生成doc文档】

/**
 * 注解 java doc演示
 * @author Alse
 * @version 1.0
 * @since 1.5
 */
public class AnnoDoc {

    /**
     * 计算两数的和
     * @param a 整数
     * @param b 整数
     * @return 两数的和
     */
    public int add(int a, int b) {
        return a + b;
    }
}
#生成javadoc文档
 javadoc className.java

2、代码分析:通过代码里标识的元数据对代码进行分析【使用反射】

3、编译检查:通过代码里标识的元数据让编译器能够实现基本的编译检查

JDK中预定义的一些注解

@Override:重载
@Deprecated:表示已过期
@SuppresssWarnings:压制警告

自定义注解

格式:
public @interface MyAnno {
    int age();
    String name()  default "Alse";
    String[] hobby();
}
本质:
import java.lang.annotation.Annotation;
public interface MyAnno extends Annotation {}
使用:
@MyAnno1(age = 1,hobby = {"eat","sleep"})
public class TestAnno1 {
}
属性:

1、属性的返回值类型:

2、定义了属性,在使用时需要给属性赋值

元注解:
用于描述注解的注解

@Target:描述注解的作用域

@Target 取值:
  ElementType.TYPE:可以作用与类上
  ElementType.METHOD:可以作用域方法上
  ElementType.FIELD:可以作用于成员变量上

@Retention:描述注解被保留的阶段,一般使用:RetentionPolicy.Runtime

@Retention 取值:
  RetentionPolicy.SOURCE:在编译时注解就被舍弃
  RetentionPolicy.CLASS:注解会被编译,但是在运行时被舍弃,默认值
  RetentionPolicy.Runtime:注解在运行时依然生效

@Documented:描述注解是否被抽取到api文档中
@Inherited:描述注解是否可以被继承

示例(一般自定义注解使用Target、Retention)
import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno1 {}
注解的使用
Demo1,通过注解调用类
/**
 * 准备调用的类
 */
public class HelloAnnotation {
    public void sayHello() {
        System.out.println("hello annotation...");
    }
}
/**
 * 获取类名、方法名的注解
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCall {
    String className();
    String methodName();
}
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 测试类
 */
@MyCall(className = "com.example.study.annotation.HelloAnnotation", methodName = "sayHello")
public class TestHello {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        // 获取注解定义位置的对象(Class,Method,Field)
        // 获取类对象,并获取类类中的注解 MyCall
        Class<TestHello> clz = TestHello.class;
        MyCall annotation = clz.getAnnotation(MyCall.class);
        // 使用注解获取类名和方法名
        String targetClzName = annotation.className();
        String targetMethodName = annotation.methodName();
        // 反射
        // 加载类
        Class targetClz = Class.forName(targetClzName);
        // 实例化
        Object obj = targetClz.newInstance();
        // 获取对象中的方法
        Method method = targetClz.getMethod(targetMethodName);
        // 执行方法
        method.invoke(obj);
    }
}

执行结果

hello annotation...
Demo2,通过注解实现测试函数
/**
 * 被测对象
 */
public class Calculator {

    @MyTest
    public void add() {
        System.out.println("1 + 0 = " + (1 + 0));
    }

    @MyTest
    public void sub() {
        System.out.println("1 - 0 = " + (1 - 0));
    }

    @MyTest
    public void mul() {
        System.out.println("1 * 0 = " + (1 * 0));
    }

    @MyTest
    public void div() {
        System.out.println("1 / 0 = " + (1 / 0));
    }
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 用于标注测试方法的注解
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {
}
import java.lang.reflect.Method;

/**
 * 对注解进行解析,并执行被注解标注的函数
 */
public class TestMyTest {
    public static void main(String[] args) {
        // 创建对象
        Calculator calculator = new Calculator();
        // 获取类
        Class clz = calculator.getClass();
        // 获取类下面的所有方法
        Method[] methods = clz.getMethods();
        // 定义执行次数,成功,失败次数
        int total = 0;
        int success = 0;
        int failed = 0;
        // 执行测试
        for (Method method:methods) {
            if (method.isAnnotationPresent(MyTest.class)) {
                // 如果有 Mytest 注解则执行方法
                try {
                    method.invoke(calculator);
                    success++;
                    System.out.println(method.getName()+"方法执行成功!");
                } catch (Exception e) {
                    failed++;
                    System.out.println(method.getName()+"方法执行失败!");
                    System.out.println("异常名称:"+e.getCause().getClass().getSimpleName());
                    System.out.println("异常原因:"+e.getCause().getMessage());
                } finally {
                    total++;
                }
                System.out.println("----------------------");
            }
        }

        System.out.println("共完成"+total+"条测试");
        System.out.println("成功:"+success+"条,失败:"+failed+"条。");

    }
}

执行结果

1 + 0 = 1
add方法执行成功!
----------------------
1 - 0 = 1
sub方法执行成功!
----------------------
div方法执行失败!
异常名称:ArithmeticException
异常原因:/ by zero
----------------------
1 * 0 = 0
mul方法执行成功!
----------------------
共完成4条测试
成功:3条,失败:1条。
上一篇 下一篇

猜你喜欢

热点阅读