设为首页 加入收藏

TOP

JDK中注解的底层实现(一)
2018-10-10 04:11:27 】 浏览:563
Tags:JDK 注解 底层 实现

用Java快三年了,注解算是一个常用的类型,特别是在一些框架里面会大量使用注解做组件标识、配置或者策略。但是一直没有深入去探究JDK中的注解到底是什么,底层是怎么实现了?于是参考了一些资料,做了一次稍微详细的分析。


参考JavaSE-8里面的JLS-9.6对注解的描述如下:


anno-1


注解的声明如下:


{InterfaceModifier} @ interface Identifier AnnotationTypeBody


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


其中:


既然所有注解类型的父接口都是java.lang.annotation.Annotation,那么我们可以看一下Annotation接口的文档:


JavaSE-8中的文档对Annotation的描述和JLS-9.6中差不多,不过最后指明了可重复注解的兼容性考虑的问题,可重复注解在JDK1.8中由元注解@Repeatable实现。下面基于JDK8的最后一个版本java version 1.8.0_181探究一下注解在JDK中的底层实现。


我们先定义一个十分简单的Counter注解如下:


package club.throwable.annotation;


import java.lang.annotation.*;


@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.TYPE)
public @interface Counter {


    int count() default 0;
}


我们先从直接使用@Counter注解,从直观上观察@Counter实例的类型:


@Counter(count = 1)
public class Main {


    public static void main(String[] args) throws Exception{
        Counter counter = Main.class.getAnnotation(Counter.class);
        System.out.println(counter.count());
    }
}


anno-2


@Counter实例从Debug过程中观察发现是JDK的一个代理类(并且InvocationHandler的实例是sun.reflect.annotation.AnnotationInvocationHandler,它是一个修饰符为default的sun包内可用的类),为了验证这一点我们使用JDK的反编译命令查看@Counter的字节

码:


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


@Counter反编译后的字节码如下:


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          &nbs
编程开发网

首页 上一页 1 2 3 4 5 6 下一页 尾页 1/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇什么是Hibernate延时加载? 下一篇JVM自定义类加载器加载指定classP..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

array(4) { ["type"]=> int(8) ["message"]=> string(24) "Undefined variable: jobs" ["file"]=> string(32) "/mnt/wp/cppentry/do/bencandy.php" ["line"]=> int(217) }