注解

从JDK5开始,Java增加对元数据的支持,也就是注解,注解与注释是有一定区别的,可以把注解理解为代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通过注解开发人员可以在不改变原有代码和逻辑的情况下在源代码中嵌入补充信息。

注解,可以看作是对 一个 类/方法 的一个扩展的模版,每个 类/方法 按照注解类中的规则,

来为 类/方法 注解不同的参数,在用到的地方可以得到不同的 类/方法 中注解的各种参数与值。

注解也就是Annotation,相信不少人也和我之前一样以为和注释和doc一样,是一段辅助性的文字,其实注解不是这样的。

从JDK5开始,java增加了对元数据(描述数据属性的信息)的支持。其实说白就是代码里的特殊标志,

这些标志可以在编译,类加载,运行时被读取,并执行相应的处理,以便于其他工具补充信息或者进行部署。

JDK的内置注解

  • @Override :检测被注解标注的方法知否是继承自父类(接口)的
  • @Deprecated :该注解标注的内容,表示已过时
  • @SuppressWarnings :压制警告,一般传递参数all,@SuppressWarnings("all")

自定义注解

1.格式:

元注解

public @interface 注解名称{}

2.本质:注解本质上就上一个接口,该接口默认继承Annotation接口

public interface 注解名称 extends java.lang.annotation.Annotation{}

3.属性:接口中的抽象方法
  • 要求:
    • ①属性的返回值类型
      • 基本数据类型
      • String
      • 枚举
      • 注解
      • 以上类型的数组
    • ②定义了属性,在使用时需要给属性赋值
      • 如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不进行属性的赋值
      • 如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义其值即可
      • 数组赋值时,值使用{}包裹起来,如果数组中只有一个值,则{}可以省略
4.元注解:用于描述注解的注解
  • @Target :描述注解能够作用的位置
    • ElementType取值:
      • TYPE :作用于类上
      • METHOD:作用于方法上
      • FIELD :作用于成员变量上
  • @Retention :描述注解被保留的阶段
    • @Retention(RetentionPolicy.RUNTIME):当前被描述的注解,会保留到class字节码文件中,并被JVM读取到
  • @Documented :描述注解是否被抽取到api文档中
  • @Inherited :描述注解是否被子类继承

注解-解析

1.获取注解定义位置的对象 (Class, Method, Field)
2.获取指定的注解

​ getAnnotation(Class) :其实就是在内存中生成了一个该注解接口的子类实现对象

3.调用注解中的抽象方法获取配置的属性值
package com.vun.annotation;

public class Demo1{
    public void show(){
        System.out.println("demo1...show...");
    }
}
package com.vun.annotation;

// 自定义Pro注解
@Target({ElementType.TYPE}) // 该注解作用于类上
@Retention(RetentionPolicy.RUNTIME) // 注解保留到class字节码文件中,并被JVM读取到
public @interface Pro{
    String className();
    String methodName();
}
package com.vun.annotation;

@Pro(className="com.vun.annotation.Demo1", methodName="show")
public class ReflectTest{
    public static void main(String[] args){
        // 1.解析注解
        Class<ReflectTest> reflectTestClass = ReflectTest.class;
        // 2.获取上边的注解对象
        //其实就是在内存中生成了一个该注解接口子类的实现对象
        Pro an = reflectTestClass.getAnnotation(Pro.class);
        // 3.调用注解对象中定义的抽象方法,获取返回值
        String className = an.className();
        String methodName = an.methodName();
        // 4.加载该类进入内存
        Class cls = Class.forName(className);
        // 5.创建对象
        Object obj = cls.newInstance();
        // 6.获取方法对象
        Method method = new cls.getMethod(methodName);
        // 7.调用执行方法
        method.invoke(obj);
    }
}

// 控制台输出结果
demo1...show...

posted @ 2022-01-28 14:16  早晨9点  阅读(41)  评论(0)    收藏  举报