# 注解

**概念**：和注释一样，都是解释说明程序。但注解是给计算机看的。不改变原有的逻辑，JVM在编译或运行期读取注解，根据不同的注解类型做相应的处理。

**定义**：注解（Annotation）/元数据。一种代码级别的说明。JDK1.5后引入可声明在包、类、字段、方法、局部变量、方法参数等的前面，对元素进行说明，注释。

**本质**：注解本质上就是一个接口，默认继承Annotation接口（lang包下）

**使用注解**：@注解名称

**作用**：

* ①编写文档：生成文档doc文档
* ②代码分析：对代码进行分析【使用反射】
* ③编译检查：编译器能实现基本的编译检查【Override】

**常用注解**：@Override ：重写；@Deprecated：表示已过时；@SuppressWarnings：压制警告。一般传递参数all【@SuppressWarnings("all")】

## 自定义注解

格式：

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

属性：接口中的抽象方法。返回值类型【基本数据类型、String、枚举、 注解以及它们的数组】

要求：

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

示例

```
package com.sire.source.jdknew.annotation;
/*注解演示*/
// 定义注解
@interface MyAnno1 {
    /*属性：基本数据 字符串 注解 枚举以及它们的数组*/
    int intVal();
    String strVal() default "sire";// 加上默认值在使用注解的时候可以不用复制
   /* MyAnn anVal();
    Sire enuVal();*/
    int[] arrVal();
    int value();
}
@interface MyAnn {}
enum Sire{
    aa;
}
// 使用注解
/*@MyAnno1(intVal = 23,arrVal = 34)*/
@MyAnno1(intVal = 23,arrVal = {2,6},value= 45)
public class MyAnno {}
```

## 元注解

**概述**：用于描述注解的注解

```
@Target：注解能够作用的位置。ElementType取值：TYPE：作用于类；METHOD：作用于方法；FIELD：作用于成员变量
@Retention：注解被保留的阶段。@Retention(RetentionPolicy.RUNTIME)：当前描述的注解，class字节码文件会保留，并被JVM读取。
@Documented：api文档是否会抽取到注解。
@Inherited：描述注解是否被子类继承
```

示例

```java
package com.sire.source.jdknew.annotation;

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

/*演示元注解*/
@Target(ElementType.METHOD)
@interface Anno2{
    int value();
}
/*@Anno2(23) 报错，只能允许在方法上*/
public class TestAnno2 {
    @Anno2(23)
    public void run(){}
}
```

## 综合案例

概述：在类上加自定义注解并写一个测试类进行测试

### 自定义注解

```java
package com.sire.source.jdknew.annotation;

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 {
}
```

### 计算器类

```java
package com.sire.source.jdknew.annotation;
/*计算器*/
public class Calc {
    @check
    public void add(){
        System.out.println(Integer.parseInt("a"));
        System.out.println("1+0="+(1+0));
    }
    @check
    public void sub(){
        System.out.println("1-0="+(1-0));
    }
    @check
    public void mut(){
        System.out.println("1*0="+(1*0));

    }@check
    public void del(){
        System.out.println("1/0="+(1/0));
    }

}
```

### 测试类

```java
package com.sire.source.jdknew.annotation;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;

/*测试方法*/
public class TestCalc {
    public static void main(String[] args) throws Exception {
        Calc c = new Calc();
        // 1.获取对象
        Class<Calc> clazz = (Class<Calc>) c.getClass();
        // 2.获取所有方法
        Method[] methods = clazz.getMethods();
        int num = 0;// 异常出现次数
        // 异常保存
        BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));
        // 3.循环所有方法
        for(Method method:methods){
            if(method.isAnnotationPresent(check.class)){
                try {
                    // 4.唤醒方法
                    method.invoke(c);
                } catch (Exception e) {
                    num++;
                    // 保存异常信息
                    bw.write("第"+num+"次异常");
                    bw.newLine();
                    bw.write("出现异常的方法："+method.getName());
                    bw.newLine();
                    bw.write("异常名称："+e.getCause().getClass().getName());
                    bw.newLine();
                    bw.write("异常信息："+e.getCause().getMessage());
                    bw.newLine();
                }
            }
        }
        bw.write("---------------------------------------\n");
        bw.write("总共发生了"+num+"次异常");
        // 6.刷新关闭
        bw.flush();
        bw.close();
    }
}
```

效果

控制台

![](/files/-LxWYWXIEIM-9bn5U1Qj)

文本文件内容

![](/files/-LxWYZwn7wTgQBpdflwT)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://xiaoxiami.gitbook.io/java/javaji-chu/mian-xiang-dui-xiang/gao-ji-te-xing/zhu-jie.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
