java 注解(Annotations)的字节码详解

注解可以标注在class、field、method上,同时又可以分为编译期的注解,运行期的注解。
这篇文章会结合jvm规范3.1.5说明注解在字节码中的位置。

一 、描述

注解可以标注在classinterfacefiledsmethodmethod parameterstype parameters。注解甚至可以作用在包级别package
类似的所有的组件基本上都有一个Attribute区域,注解是一种Attribute被放置在部分。
使用method的字节码来举例

1.1 methods 方法表

方法表在class文件的位置

ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    // 这里 
    u2             methods_count;
    method_info    methods[methods_count];
    // 结束
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

metod_info的的数据结构

method_info {
    u2             access_flags;
    u2             name_index;
    u2             descriptor_index; 
    // 这里
    u2             attributes_count;
    attribute_info attributes[attributes_count];
    // 结束
}

Attribute的数据结构
属性是变长的,种类有很多。分为jvm规范中预制的,也有各厂家自定义的。但是有一个统一的格式。

attribute_info {
    u2 attribute_name_index;
    u4 attribute_length;
    u1 info[attribute_length];
}

2.2 annotations的数据结构

除了方法表之外,很多地方都有一个属性表。注解作为一个属性被放在这个位置。
注解属性结构细分有7种

type descriptor
RuntimeVisibleAnnotations 运行时可见
RuntimeVisibleAnnotations 运行时不可见
RuntimeVisibleParameterAnnotations 标注在参数上,运行时可见的参数型注解
RuntimeInvisibleParameterAnnotations 标注在参数上,运行时不可见的参数型注解
RuntimeVisibleTypeAnnotations 标注在例行上比如泛型,运行时可见的类型注解
RuntimeInvisibleTypeAnnotations 标注在例行上比如泛型,运行时不可见的类型注解
AnnotationDefault 注解的默认值

2.2.1 RuntimeVisibleAnnotations

顾名思议,就是运行期(runtime) 可见的。延伸一点,运行期可以通过函数等方式获取到的。
注解表结构

RuntimeVisibleAnnotations_attribute {
   
    u2         attribute_name_index;
    u4         attribute_length;
    u2         num_annotations;
    annotation annotations[num_annotations];
}
2.2.1.1 annotation的结构

继上一步,理解注解的结构和注解代码定义是分不开的

annotation 代码定义

这个是一个完整的定义

@Retention(RetentionPolicy.RUNTIME)
//@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
public @interface Info {
   
    // value
    int age();
    String name();
    String descriptor() default "simple annotation";

}

一个注解可以继承注解(@Retention、@Target)
也需要定义字节的成员(int age();)

使用时如下,这是一个打印了Info注解的方法

public class TestInfo {
   
    @Info(age = 0, name = "baby")
    public void born() {
   
        System.out.println("human born");
    }

    public static void main(String[] args) throws Exception {
   
        TestInfo ti = new TestInfo()<
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值