目录

Life in Flow

知不知,尚矣;不知知,病矣。
不知不知,殆矣。

X

Annotation

annotation

  • 注解是在 JDK5 时引入的新特性,其实就是代码里的特殊标记
  • 注解也被称为元数据,是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用
  • 允许开发人员在不改变源代码的情况下,在源代码中添加一些元数据
  • 以便让编译器或者其他工具可以读取这些元数据,从而实现更高级的功能

应用场景

  • 生成文档
  • 编译时进行格式检查,如 @Override
  • 替代配置文件功能,比如 Spring 的注解
  • 和反射组合应用,自己封装框架组件

Java 自带的标准注解

这些注解后编译器就会进行检查

  • @Override 标记覆写父类的方
  • @Deprecated 标记被修饰的类或类成员、类方法已废弃、过时
  • @SuppressWarnings 用于关闭对类、方法、成员编译时产生的特定警告,

元注解

用于定义注解的注解
元注解也是Java自带的标准注解,只不过用于修饰注解,比较特殊。

@Target表示该注解用于什么地方

  • ElementType.CONSTRJCTOR 用在构造器
  • ElementType.FIELD 用于描述域-属性上
  • ElementType.METHOD 用在方法上
  • ElementType.TYPE 用在类或接口上
  • ElementType.PACKAGE 用于描述包

@Retention: 表示在什么级别保存该注解信息

  • RetentionPolicy.SOURCE 保留到源码上
  • RetentionPolicy.CLASS 保留到字节码上
  • RetentionPolicy.RUNTIME 保留到虚拟机运行时(最多,可通过反射获取)

@Documented: 将此注解包含在javadoc中

@Inherited: 是否允许子类继承父类中的注解

@Repeatable: 注解是用来标注一个注解在同一个地方可重复使用的一个注解,比如说你定义了一个注解,如果你的注解没有标记@Repeatable这个JDK自带的注解,那么你这个注解在引用的地方就只能使用一次。

image.png

声明注解

@interface 相当于 Java 声明类的 class

  • 用来声明一个注解,可以通过 default 来声明参数的默认值
  • 自定义注解时,自动继承了 java.lang.annotation.Annotation 接口
  • 通过反射可以获取自定义注解
1@元注解
2public @interface 注解名称{
3	// 属性列表
4}

自定义注解

用户可以根据自己的需求定义注解 image.png

自定义支持优先级的单元测试

需求:实现一个类似junit单元测试的注解,可以批量运行某个类的全部加了注解的方法。需要支持支持自定义优先级执行,且可以不启动某个方法。

反射获取自定义注解
作用范围Class、Method、Field都支持

方法 说明
getAnnotations( ) 获取类上的所有注解内容
getAnnotation(XXX.class) 获取到注解的内容
isAnnotationPresent(XXX.class) 判断某个注解是否存在

注解类:Test

 1package com.soulboy.anno;
 2
 3import java.lang.annotation.*;
 4
 5@Inherited
 6@Documented
 7@Target(ElementType.METHOD)
 8@Retention(RetentionPolicy.RUNTIME)
 9public @interface Test {
10
11    /**
12     * 优先级
13     *
14     * @return
15     */
16    int priority() default 0;
17
18    /**
19     * 是否要禁用
20     */
21    boolean disable() default false;
22
23}

在方法上使用注解:TestCase

 1package com.soulboy.anno;
 2
 3public class TestCase {
 4    @Test(priority = 1,disable = false)
 5    public void testCase1(){
 6        System.out.println("测试用例1");
 7    }
 8    @Test(priority = 2,disable = false)
 9    public void testCase2(){
10        System.out.println("测试用例2");
11    }
12
13    @Test(priority = 3,disable = true)
14    public void testCase3(){
15        System.out.println("测试用例3");
16    }
17    @Test(priority = 4,disable = false)
18    public void testCase4(){
19        System.out.println("测试用例4");
20    }
21}

基于方法上的注解元信息进行相应的操作:AnnoTest

 1package com.soulboy.anno;
 2
 3import java.lang.reflect.InvocationTargetException;
 4import java.lang.reflect.Method;
 5import java.util.ArrayList;
 6import java.util.Comparator;
 7import java.util.List;
 8
 9public class AnnoTest {
10    public static void main(String[] args) {
11        // 获取TestCase类实例:invoke的时候需要用
12        TestCase testCase = new TestCase();
13        // 获取TestCase类
14        Class<TestCase> testCaseClass = TestCase.class;
15        // 获取全部声明的方法
16        Method[] declaredMethods = testCaseClass.getDeclaredMethods();
17
18        // 定义一个List,存储全部有Test注解,且要运行的方法
19        List<Method> methodList = new ArrayList<>();
20
21        // 遍历方法,获取有注解且要运行
22        for (Method method : declaredMethods) {
23            if (method.isAnnotationPresent(Test.class)) {
24                //获取方法上的注解
25                Test annotation = method.getAnnotation(Test.class);
26                // disable不为true的才会运行
27                if (!annotation.disable()) {
28                    // 要运行的方法添加到list
29                    methodList.add(method);
30                }
31            }
32        }
33        // 根据优先级对要运行的方法进行排序, priority数字越小,优先级越高
34        methodList.sort(Comparator.comparingInt(obj -> obj.getAnnotation(Test.class).priority()));
35
36        // 遍历list,在invoke调用对应的方法
37        for (Method method : methodList) {
38            try {
39                //执行全部带有注解的方法
40                method.invoke(testCase);
41            } catch (IllegalAccessException e) {
42                throw new RuntimeException(e);
43            } catch (InvocationTargetException e) {
44                throw new RuntimeException(e);
45            }
46        }
47    }
48}

作者:Soulboy