Java八股(注解)

注解的原理

注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。

我们通过反射获取注解时,返回的是Java运行时生成的动态代理对象。通过代理对象调用自定义注解的方法,会最终调用AnnotationInvocationHandler的invoke方法。该方法会从memberValues这个Map中索引出对应的值。而memberValues的来源是Java常量池。

注解解析的底层实现

注解本质上是一种特殊的接口,它继承自 java.lang.annotation.Annotation 接口,所以注解也叫声明式接口,例如,定义一个简单的注解:

编译后,Java 编译器会将其转换为一个继承自 Annotation 的接口,并生成相应的字节码文件。

根据注解的作用范围,Java 注解可以分为以下几种类型:

  • 源码级别注解 :仅存在于源码中,编译后不会保留(@Retention(RetentionPolicy.SOURCE))。
  • 类文件级别注解 :保留在 .class 文件中,但运行时不可见(@Retention(RetentionPolicy.CLASS))。
  • 运行时注解 :保留在 .class 文件中,并且可以通过反射在运行时访问(@Retention(RetentionPolicy.RUNTIME))。

只有运行时注解可以通过反射机制进行解析。

Java注解的作用域

注解的作用域(Scope)指的是注解可以应用在哪些程序元素上,例如类、方法、字段等。Java注解的作用域可以分为三种:

  1. 类级别作用域:用于描述类的注解,通常放置在类定义的上面,可以用来指定类的一些属性,如类的访问级别、继承关系、注释等。
  2. 方法级别作用域:用于描述方法的注解,通常放置在方法定义的上面,可以用来指定方法的一些属性,如方法的访问级别、返回值类型、异常类型、注释等。
  3. 字段级别作用域:用于描述字段的注解,通常放置在字段定义的上面,可以用来指定字段的一些属性,如字段的访问级别、默认值、注释等。

除了这三种作用域,Java还提供了其他一些注解作用域,例如构造函数作用域和局部变量作用域。这些注解作用域可以用来对构造函数和局部变量进行描述和注释。