Java学习——注解

 

注释和注解的区别

注释:用文字来描述程序的,拿来给程序员看的。

注解:通俗一点来说就是说明程序的,拿来给计算机编译器、解析程序使用的。注解不是程序的一部分,可以理解为注解就是一个标签。

注解

定义:注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。注解就是增强型的注释(可被计算机识别的注释),本质是接口。注解本身并没有任何功能(因为它只是注释,本质也只是接口),需要其他代码支撑,它才能体现价值。

作用分类:
        ①编写文档:通过代码里标识的注解生成文档【生成文档doc文档】
        ②代码分析:通过代码里标识的注解对代码进行分析【使用反射】
        ③编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查【Override】

功能注解

Java预置的功能注解,主要分为:

@Override:检测被该注解标注的方法是否是继承自父类(接口)的,该注解修饰的目标方法,必须是重写基类方法,或实现对应接口方法,否则编译器会报错。

@Deprecated:该注解修饰的目标,表示已经过时,不推荐使用。编码时,使用该注解的目标,会有划线提示。

@SuppressWarnings:压制警告,该注解修饰的目标,将会忽略某些异常(由注解的value指定),从而通过编译器编译。

@SafeVarargs:该注解修饰的构造函数(只能修饰构造函数),将会忽略可变参数带来的警告。该注解于Java7引入。

@FunctionalInterface:该注解修饰的接口,为函数式接口。如java.util.function下的Consumer自定义注解

 

自定义注解

* 格式

元注解
public @interface 注解名称{
	属性列表;
}

* 本质:注解本质上就是一个接口,该接口默认继承Annotation接口。

public interface MyAnno extends java.lang.annotation.Annotation {}

*属性:接口中的抽象方法
            * 要求:
                1. 属性的返回值类型有下列取值
                    * 基本数据类型
                    * String
                    * 枚举
                    * 注解
                    * 以上类型的数组

                2. 定义了属性,在使用时需要给属性赋值
                    1. 如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不进行属性的赋值。
                    2. 如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义值即可。
                    3. 数组赋值时,值使用{}包裹。如果数组中只有一个值,则{}可以省略

自定义注解分为以下步骤:

  • [必选] 使用@interface来构建自定义注解。一般在创建自定义注解的同时,就达成了该要求。
  • [可选] 使用@Target元注解。通过该注解,描述该注解能够作用的位置,确定自定义注解的作用目标类型。注意:如果目标注解没有使用该注解,则目标注解可以用于除了TYPE_PARAMETER和TYPE_USE以外的任何地方(这两个类型都是Java8新添加的)。
  • [可选] 使用@Retention元注解。通过该注解,描述该注解被保留的阶段,明确自定义注解的生命周期,或者说自定义注解作用域。如果目标注解没有使用该注解,则默认使用RetentionPolicy.CLASS
  • [可选] 添加成员变量。格式为“long value() default 1000L;”,与Java8的接口成员变量非常类似。注意:注解的成员变量只能采用无参方法表示。并且注解的成员变量,只能采用基本数据类型(char,boolean,byte、short、int、long、float、double)和String、Enum、Class、annotations数据类型,以及这一些类型的数组。
  • [可选] 使用自定义注解。自定义注解的使用领域很多,主要分为两个方向:

                    *利用已有框架,不需要自己实现相关逻辑,自定义注解多作为标记注解。如配合SpringBoot的注解,形成自己的注解(相关的逻辑由SpringBoot自己处理)

                    *利用已有框架,需要自己实现部分逻辑(不涉及反射),但需要关联已有框架,并实现对应接口。如Validation框架的自定义校验注解。

                    *可选择已有框架,需要自己实现诸多逻辑。如在AOP(在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。)中,我们常常需要通过反射,获取自定义注解的信息(如参数等),或者自定义注解修饰的目标的信息(如参数,方法名等)。

案例:简单的测试框架

运算类

package demo;

/*
	定义的计算器类
 */
public class Calculator {

    //加法
    @Check
    public void add(){
        String str = null;
        str.toString();
        System.out.println("1 + 0 =" + (1 + 0));
    }
    //减法
    @Check
    public void sub(){
        System.out.println("1 - 0 =" + (1 - 0));
    }
    //乘法
    @Check
    public void mul(){
        System.out.println("1 * 0 =" + (1 * 0));
    }
    //除法
    @Check
    public void div(){
        System.out.println("1 / 0 =" + (1 / 0));
    }


    public void show(){
        System.out.println("永无bug...");
    }

}

校验类

package demo;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Check {
}

测试类

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 c = new Calculator();
        //2.获取字节码文件对象
        Class cls = c.getClass();
        //3.获取所有方法
        Method[] methods = cls.getMethods();

        int number = 0;//出现异常的次数
        BufferedWriter bw = new BufferedWriter(new FileWriter("bug.txt"));


        for (Method method : methods) {
            //4.判断方法上是否有Check注解
            if(method.isAnnotationPresent(Check.class)){
                //5.有,执行
                try {
                    method.invoke(c);
                } catch (Exception e) {
                    //6.捕获异常

                    //记录到文件中
                    number ++;

                    bw.write(method.getName()+ " 方法出异常了");
                    bw.newLine();
                    bw.write("异常的名称:" + e.getCause().getClass().getSimpleName());
                    bw.newLine();
                    bw.write("异常的原因:"+e.getCause().getMessage());
                    bw.newLine();
                    bw.write("--------------------------");
                    bw.newLine();

                }
            }
        }

        bw.write("本次测试一共出现 "+number+" 次异常");

        bw.flush();
        bw.close();



    }

}

效果展示

总结

注解是什么:增强型的注释,本质是接口

元注解是什么:注解的注解,作用是为了标识目标注解。包括@Target,@Retention,@Documented,@Repeatable,@Inherited.

预置注解是什么:JDK自带的经典功能注解,如@Override,@Deprecated,@SuppressWarnings,@SafeVarargs,@FunctionalInterface。

自定义注解如何实现:主要分为五步,但是其中必要的步骤,就一步:使用@interface来构建自定义注解。

 

Guess you like

Origin blog.csdn.net/weixin_44684272/article/details/117619524