JAVA注解

注解

注解:注解(Annotation),也叫元数据。一种代码级别的说明,它是JKD1.5及以后版本映入的一个特性,与类,接口,枚举是在桶一个层次。它可以声明在包,类,字段,方法,局部变量,方法参数等的前面,用来对这些元素进行说明和注释。

注解:说明程序,给计算机看的。

注释:用文字描述程序,给人看的。

使用注解:@注解名称

作用分类:

  1. 编写文档:通过代码里的标识的注解生成文档[生成doc文档]
  2. 代码分析:通过代码里的标识的注解对代码进行分析[使用反射]
  3. 编译检查:通过代码里的标识的注解让编译器能够实现基本的编译检查[Override]

JDK中预定的注解

@Override:检查被该注解标注的方法是否继承父类(接口)的

@Deprecated:该注解标注的内容,表示已过时

@SuppressWarnings:压制警告

  • 一般传递参数all @SuppressWarnings(“all”) 放在类的上面

自定义注解

格式:

  • 元注解
  • public @interface 注解名称{}

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

public @interface MyAnno{

}
  • 以上通过javac编译文件之后javap反编译得到以下东西
public interface MyAnno extends java.lang.annotation.Annotation {
}

属性:接口中可以定义的抽象方法

  • 要求
    1. 属性的返回值类型
      • 基本数据类型
      • String
      • 枚举
      • 注解
      • 以上类型的数组
    2. 定义了属性,在使用时需要给属性赋值
      • 如果定义属性时,使用default关键字给属性初始化值,则使用注解,可以不进行属性的赋值
      • 如果只有一个属需要赋值,并且属性的名称是value,则value可以省略,直接定义即可
      • 数组赋值时,值使用{}包裹。如果数组只有一个元素可以不用加括号

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

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

在程序中使用(解析)注解:获取注解中定义的属性值

  1. 获取注解定义的位置的对象(Class,Method,Field)
  2. 获取指定的注解
    • getAnnotation(Class)// 其实就是在内存中生成了一个该注解接口的子列实现对象
  3. 调用注解的抽象方法获取配置的属性值
@Target({ElementType.TYPE})//只能作用在类上
@Retention(RetentionPolicy.RUNTIME)//在运行时可以加载进class并且被jvm读取
public @interface Pro {
    String className();
    String methodName();
}
@Pro(className = "annotation.Demo1",methodName = "show")
public class ReflectTest {
    public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //1.解析注解
        //1.1获取该类的字节码文件对象
        Class<ReflectTest> reflectTestClass = ReflectTest.class;
        //2.获取上面的注解对象
        Pro an = reflectTestClass.getAnnotation(Pro.class);//在内存中生成了一个该注解接口的子类实现对象
        //3.调用注解对象的抽象方法,获取返回值
        String className = an.className();
        String classMethod = an.methodName();
        System.out.println(className);
        Class demoClass = Class.forName(className);
        Object demo1 =  demoClass.newInstance();
        Method demoMethod = demoClass.getMethod(classMethod);
        demoMethod.invoke(demo1);
    }
}

案例

捕获一个类有Check注解的方法的异常

测试类
package annotation;

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

public class TestCheck {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, IOException {
        Demo demo = (Demo) Class.forName("annotation.Demo").newInstance();
        //获取字节码文件
        Class cls= demo.getClass();
        //获取所有方法
        int num=0;
        BufferedWriter bw = new BufferedWriter(new FileWriter("bug1.txt"));
        Method[] methods = cls.getMethods();
        for (Method method:methods){
            //判断是否有注解
            if(method.isAnnotationPresent(Check.class)){//isAnnotationPresent()放法判断是否存在注解
                try {
                    method.invoke(demo);
                }catch (Exception e) {
                    //记录到文件中
                    num++;
                    bw.write(method.getName()+"出现异常了\n");
                    bw.write("异常原因"+e.getCause()+"\n");
                    bw.write("------------------------------------------------\n");

                }

            }
        }
        bw.close();
    }
}

注解

package annotation;

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

/**
 * 简单的测试框架
 *
 * 当主方法执行后,会自动自行检查的所有方法(Check注解的方法),判断方法是否有一次,记录到文件中
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)//必须有这个元注解 不然运行的时候 JVM检查不到Check注解
public @interface Check {
}
Demo类
package annotation;

import com.sun.org.apache.bcel.internal.generic.LDIV;

public class Demo {

    @Check
    public void div(){
        System.out.println(1/0);
    }
    @Check
    public void p(){
        System.out.println(100);
    }

    public static void main(String[] args) {
        new Demo().div();
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值