• Java 注解


    注解

    • 概念:说明程序,给计算机看
    • 注释:文字描述程序,方便理解
    • 定义:注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。

    作用分类:

    (1)编写文档:通过代码里标识的元数据生成文档【生成文档doc文档】javadoc
    (2)代码分析:通过代码里标识的元数据对代码进行分析【使用反射】
    (3)编译检查:通过代码里标识的元数据让编译器能够实现基本的编译检查【@ Override】

    //编写文档演示
    package annotation;
    
    /**
     * 注释javadoc 演示
     *
     * @author ljk
     * @version 1.0
     * @since 1.5
     */
    public class AnnoDemo1 {
    
        /**
         * 计算两数之和
         * @param a int
         * @param b int
         * @return 两数之和
         */
        public int add(int a, int b){
            return a + b;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在该java文件下使用 shift + 右键
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    打开index.html
    在这里插入图片描述

    JDK中预定义的一下注解

    (1)@Override:检测被该注解标注的方法是否是继承自父类 / 接口的
    (2)@Deprecated:该注解标注的内容,已过时(仍能使用)
    (3)@SuppressWarnings(”all“):压制警告,一般传递参数all

    package annotation;
    
    
    @SuppressWarnings("all")
    public class AnnoDemo2 {
    
        @Override
        public String toString(){
            return super.toString();
        }
    
        @Deprecated
        public void show1(){
            //方法过时
        }
    
        public void demo(){
            show1();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    在这里插入图片描述

    自定义注释

    • 格式:public @interface 注解名称{}
    • 本质:注解本质上就是一个接口,该接口默认继承Annotation接口
    • 属性:接口中定义的抽象方法
      (1)属性的返回值类型:基本数据类型,String,枚举,注解,以上类型的数组
      (2)定义了属性,在使用时需要给属性赋值
      1.如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不进行属性赋值
      2.如果只有一个属性需要赋值,并且属性的名称时value,则value可以省略,直接定义值就可以
      3.数组赋值时,值使用{}包裹,如果数组中只有一个值,则{}可省略
    • 元注解:用于描述注解的注解
      (1)@Target:描述注解能够作用的位置;ElementType取值:TYPE:可以作用与类上,METHOD:可以作用与方法上,FIELD:可以作用与成员变量上
      (2)Retention:描述注解能被保留的阶段;@Retention(RetentionPolicy.SOURCE)当前描述的注解,会保留到class字节码文件中,并被JVM读取到
      (3)Documented:描述注解是否被抽取到API文档中
      (4)Inherited:描述注解是否被子类继承
    package annotation;
    
    import java.lang.annotation.*;
    
    @Target(value = {ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
    @Retention(RetentionPolicy.SOURCE)
    @Documented
    @Inherited
    public @interface MyAnno {
        
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在程序中使用(解析)注解

    • 获取注解中定义的属性
      (1)获取注解中定义的对象
      (2)获取指定的注解 getAnnotation(Class)
      (3)调用注解中的抽象方法获取配置的属性值
    //注解Pro
    package annotation;
    
    import javax.xml.bind.Element;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Pro {
        String className();
        String methodName();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    //注解Pro使用
    package annotation;
    
    @Pro(className = "annotation.Demo1", methodName = "show")
    public class ReflectTest {
        public static void main(String[] args) throws Exception{
            //1.解析注解
            //获取该类的字节码文件对象
            Class<ReflectTest> reflectTestClass = ReflectTest.class;
            //2.获取注解对象
            //其实就是在内存中生成了一个该注解接口的子类实现对象
            Pro annotation = reflectTestClass.getAnnotation(Pro.class);
            //3.调用注解对象中定义的抽象方法,获取返回值
            String className = annotation.className();
            System.out.println(className);
            String methodName = annotation.methodName();
            System.out.println(methodName);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    案例:测试计算注解

    //需要测试类
    package demo;
    
    public class Calculator {
        @Check
        public void add() {
            System.out.println(1 + 0);
        }
    
        @Check
        public void sub() {
            System.out.println(1 - 0);
        }
    
        @Check
        public void mul() {
            System.out.println(1 * 0);
        }
    
        @Check
        public void div() {
            System.out.println(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
    //注解定义
    package demo;
    
    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 Check {
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    //测试类
    package demo;
    
    import java.io.BufferedWriter;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.lang.reflect.Method;
    
    /*
    简单的测试框架
    
    当主方法执行后,会自动执行被检测的方法(加了Check注解的方法),判断是否有异常,记录到文件
     */
    public class TestCheck {
        public static void main(String[] args) throws IOException {
            //1.创建计算器对象
            Calculator calculator = new Calculator();
            //2.获取字节码文件对象
            Class cls = calculator.getClass();
            //3.获取所有方法
            Method[] methods = cls.getMethods();
            //4.判断方法上是否有Check注解
            int num = 0; //记录出现异常的次数
            BufferedWriter bw = new BufferedWriter(new FileWriter("bug.txt"));
            for (Method method : methods) {
                if (method.isAnnotationPresent(Check.class)) {
                    //5.执行含Check注解的方法
                    try {
                        method.invoke(calculator);
                    } catch (Exception e) {
                        //6.捕获异常,记录到文件中
                        num++;
                        bw.write(method.getName() + "方法出现了异常");
                        bw.newLine();
                        bw.write("异常名称:" + e.getCause().getClass().getSimpleName());
                        bw.newLine();
                        bw.write("异常原因:" + e.getCause().getMessage());
                        bw.newLine();
                        bw.write("----------------------------");
                    }
                }
            }
            bw.write("本次测试一共出现:" + num + "次异常");
            bw.newLine();
            bw.flush();
            bw.close();
        }
    }
    
    
    • 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
    • 46
    • 47
    • 48
    • 49

    在这里插入图片描述

    在这里插入图片描述

    小结:

    • 注解给谁用:
      (1)编译器
      (2)给解析程序用
    • 注解不是程序的一部分,可以理解为注解就是一个标签
  • 相关阅读:
    TypeScript基本信息总结
    Java-部分知识点梳理及汇总
    业务开发时,接口不能对外暴露的解决方案
    Android多线程学习:线程池(二)
    SparkStreaming介绍
    自助点餐系统微信小程序,支持外卖、到店等
    初识《list》及手搓模拟《list》
    以违停检测为示例的利用微软云AIOT技术加速项目落地
    最简单的springboot整合websocket方式
    org.postgresql.util.PSQLException: Bad value for type long
  • 原文地址:https://blog.csdn.net/weixin_57596714/article/details/125406169