美文网首页
java 注解枚举的底层实现

java 注解枚举的底层实现

作者: hehehehe | 来源:发表于2020-11-09 20:33 被阅读0次
注解
{InterfaceModifier} @ interface Identifier AnnotationTypeBody

接口修饰符 @ interface 注解标识符 注解类型的内容

注解类型声明中的标识符指定了注解类型的名称。
如果注解类型与它的任何封闭类或接口具有相同的简单名称,则编译时会出现错误。
每个注解类型的直接父接口都是java.lang.annotation.Annotation。

javap -c -v D:\Projects\rxjava-seed\target\classes\club\Counter.class

Classfile /D:/Projects/rxjava-seed/target/classes/club/throwable/annotation/Counter.class
  Last modified 2018-10-6; size 487 bytes
  MD5 checksum 83cee23f426e5b51a096281068d8b555
  Compiled from "Counter.java"
public interface club.throwable.annotation.Counter extends java.lang.annotation.Annotation
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
Constant pool:
   #1 = Class              #19            // club/throwable/annotation/Counter
   #2 = Class              #20            // java/lang/Object
   #3 = Class              #21            // java/lang/annotation/Annotation
   #4 = Utf8               count
   #5 = Utf8               ()I
   #6 = Utf8               AnnotationDefault
   #7 = Integer            0
   #8 = Utf8               SourceFile
   #9 = Utf8               Counter.java
  #10 = Utf8               RuntimeVisibleAnnotations
  #11 = Utf8               Ljava/lang/annotation/Retention;
  #12 = Utf8               value
  #13 = Utf8               Ljava/lang/annotation/RetentionPolicy;
  #14 = Utf8               RUNTIME
  #15 = Utf8               Ljava/lang/annotation/Documented;
  #16 = Utf8               Ljava/lang/annotation/Target;
  #17 = Utf8               Ljava/lang/annotation/ElementType;
  #18 = Utf8               TYPE
  #19 = Utf8               club/throwable/annotation/Counter
  #20 = Utf8               java/lang/Object
  #21 = Utf8               java/lang/annotation/Annotation
{
  public abstract int count();
    descriptor: ()I
    flags: ACC_PUBLIC, ACC_ABSTRACT
    AnnotationDefault:
      default_value: I#7}
SourceFile: "Counter.java"
RuntimeVisibleAnnotations:
  0: #11(#12=e#13.#14)
  1: #15()
  2: #16(#12=[e#17.#18])

既然注解最后转化为一个接口,注解中定义的注解成员属性会转化为抽象方法,那么最后这些注解成员属性怎么进行赋值的呢?答案就是:为注解对应的接口生成一个实现该接口的动态代理类。直接点说就是:Java通过动态代理的方式生成了一个实现了"注解对应接口"的实例,该代理类实例实现了"注解成员属性对应的方法",这个步骤类似于"注解成员属性"的赋值过程,这样子就可以在程序运行的时候通过反射获取到注解的成员属性(这里注解必须是运行时可见的,也就是使用了@Retention(RetentionPolicy.RUNTIME),另外需要理解JDK原生动态代理和反射相关内容)。

枚举
image.png

javap -c -v D:\Projects\rxjava-seed\target\classes\club\enumeration\PhoneOsEnum.class

枚举的声明格式是:{ClassModifier} enum Identifier [Superinterfaces] EnumBody,
ClassModifier是修饰符,Identifier是枚举的名称可以类比为类名,枚举类型可以实现接口。
枚举类型不能使用abstract或者final修饰,否则会产生编译错误。
枚举类型的直接超类是java.lang.Enum。
枚举类型除了枚举常量定义之外没有其他实例,也就是枚举类型不能实例化。
枚举类型禁用反射操作进行实例化(这个特性就是Effetive Java中推荐使用枚举实现单例的原因)。

JDK中枚举的底层实现就是使用了enum关键字声明的枚举类编译后最终会变成public final修饰同时实现了泛型接口java.lang.Enum并且指定泛型参数为自身的普通Java类,而成员属性和方法实现相关都是在编译完成后就已经成型的,枚举类型的成员变量都是通过静态代码块声明的。

相关文章

  • java 注解枚举的底层实现

    注解 javap -c -v D:\Projects\rxjava-seed\target\classes\clu...

  • JDK中枚举的底层实现

    前提 上一篇文章复习介绍了JDK中注解的底层实现,跟注解一样比较常用,但是底层实现比较神秘的还有枚举类型。趁着国庆...

  • 实现validation注解进行校验枚举值

    背景: validation注解官方没有定义枚举类型的注解,于是这里自定义一个枚举类型注解,来实现对象的验证。 不...

  • Kotlin 高级编程语言特性代码实例

    定义接口 使用注解 实现接口 枚举类 enum class BizEnum 注解 annotation class...

  • 注解的实现原理

    一、注解的底层实现原理 注解的底层也是使用反射实现的,我们可以自定义一个注解来体会下。注解和接口有点类似,不过申明...

  • Effective Java 3rd-----Chapter 6

    Chapter 6 Enums and Annotations 枚举和注解 JAVA supports two s...

  • Kotlin基础1-语法上手

    概要 类在声明接口&抽象类&枚举&注解时,与 Java 相比基本一样,除了枚举&注解在声明的时候后面哟啊加上cla...

  • 查阅资料

    @IntDef的使用(替代枚举) 注解: java 集合 [https://blog.csdn.net/zhang...

  • 20170714 TypeAnnotation

    Java8新增的Type Annotation(类型注解) Java8为ElementType枚举增加了TYPE_...

  • 参数规则校验-限定枚举值的校验

    首先,定义一个基础的枚举接口,只要实现了此接口的枚举方可校验枚举值。 接下来定义我们自己的枚举值 定义枚举校验注解...

网友评论

      本文标题:java 注解枚举的底层实现

      本文链接:https://www.haomeiwen.com/subject/zyerbktx.html