class 属性表

一 class 属性计数器

attributes_count 的值表示当前 class 文件属性表的成员个数。属性表中每一项都是一个 attribute_info 结构。

二 属性表

attributes[](属性表)的每个项的值必须是 attribute_info 结构。属性表的结构比较灵活,各种不同的属性只要满足以下结构即可。

1 属性的通用格式

类型

名称

数量

含义

u2

attribute_name_index

1

属性名索引

u4

attribute_length

1

属性长度

u1

info

attribute_length

属性表

2 属性类型

属性表实际上可以有很多类型,上面看到的 Code 属性只是其中一种,Java8 里面定义了 23 种属性。下面这些是虚拟机中预定义的属性。

属性名称

使用位置

含义

Code

方法表

Java 代码编译成的字节码指令

ConstantValue

字段表

final 关键字定义的常量池

Deprecated

类,方法,字段表

被声明为 deprecated 的方法和字段

Exceptions

方法表

方法抛出的异常

EnclosingMethod

类文件

仅当一个类为局部类或者匿名类时才能拥有这个属性,这个属性用于标识这个类所在的外围方法

InnerClass

类文件

内部类列表

LineNumberTable

Code 属性

Java 源码的行号与字节码指令的对应关系

LocalVariableTable

Code 属性

方法的局部变量描述

StackMapTable

Code 属性

JDK1.6 中新增的属性,供新的类型检查检验器和处理目标方法的局部变量和操作数有所需要的类是否匹配

Signature

类,方法表,字段表

用于支持泛型情况下的方法签名

SourceFile

类文件

记录源文件名称

SourceDebugExtension

类文件

用于存储额外的调试信息

Synthetic

类,方法表,字段表

标志方法或字段为编译器自动生成的

LocalVariableTypeTable

是哟很难过特征签名代替描述符,是为了引入泛型语法之后能描述泛型参数化类型而添加

RuntimeVisibleAnnotations

类,方法表,字段表

为动态注解提供支持

RuntimeInvisibleAnnotations

类,方法表,字段表

用于指明哪些注解是运行时不可见的

RuntimeVisibleParameterAnnotation

方法表

作用与 RuntimeVisibleAnnotations 属性类似,只不过作用对象或方法

RuntimeInvisibleParameterAnnotation

方法表

作用与 RuntimeInvisibleAnnotations 属性类似,只不过作用对象或方法

AnnotationDefault

方法表

用于记录注解类元素的默认值

BootstrapMethods

类文件

用于保存 invokeddynamic 指令引用的引导方法限定符

或者(查看官网)

class 属性表

三 部分属性详解

1 ConstantValue 属性

ConstantValue 属性表示一个常量字段的值。位于 field_info 结构的属性表中。

ConstantValue_attribute{

    u2 attribute_name_index;

    u4 attribute_length;

    u2 constantvalue_index; // 字段值在常量池中的索引,常量池在该索引处的项给出该属性表示的常量值。(例如,值是 1ong 型的,在常量池中便是CONSTANT_Long)

}

2 Deprecated 属性

Deprecated 属性是在 JDK1.1 为了支持注解中的关键词 @deprecated 而引入的。

Deprecated_attribute{

    u2 attribute_name_index;

    u4 attribute_length;

}

3 Code 属性

Code 属性就是存放方法体里面的代码。但是,并非所有方法表都有 Code 属性。像接口或者抽象方法,他们没有具体的方法体,因此也就不会有 Code 属性了。Code 属性表的结构,如下表。

类型

名称

数量

含义

u2

attribute_name_index

1

属性名索引

u4

attribute_length

1

属性长度

u2

max_stack

1

操作数栈深度的最大值

u2

max_locals

1

局部变量表所需的存续空间

u4

code_length

1

字节码指令的长度

u1

code

code_lenth

存储字节码指令

u2

exception_table_length

1

异常表长度

exception_info

exception_table

exception_length

异常表

u2

attributes_count

1

属性集合计数器

attribute_info

attributes

attributes_count

属性集合

可以看到:Code 属性表的前两项跟属性表是一致的,即 Code 属性表遵循属性表的结构,后面那些则是他自定义的结构。

4 InnerClasses 属性

为了方便说明特别定义一个表示类或接口的 Class 格式为 C。如果 C 的常量池中包含某个 CONSTANT_Class_info 成员,且这个成员所表示的类或接口不属于任何一个包,那么 C 的 ClassFile 结构的属性表中就必须含有对应的 InnerClasses 属性。InnerClasses 属性是在 JDK1.1 中为了支持内部类和内部接口而引入的,位于 ClassFile 结构的属性表。

5 LineNumberTable 属性

LineNumberTable 属性是可选变长属性,位于 Code 结构的属性表。

LineNumberTable 属性是用来描述 Java 源码行号与字节码行号之间的对应关系。这个属性可以用来在调试的时候定位代码执行的行数。

  • start_pc:即字节码行号;

  • line_number:即 Java 源代码行号。

在 Code 属性的属性表中,LineNumberTable 属性可以按照任意顺序出现,此外,多个 LineNumberTable 属性可以共同表示一个行号在源文件中表示的内容,即 LineNumberTable 属性不需要与源文件的行一一对应。

// LineNumberTable属性表结构:
LineNumberTable_attribute{
    u2 attribute_name_index;
    u4 attribute_length;
    u2 line_number_table_length;
    {
        u2 start_pc;
        u2 line_number;
    } line_number_table[line_number_table_length];
}

6 LocalVariableTable 属性

LocalVariableTable 是可选变长属性,位于 Code 属性的属性表中。它被调试器用于确定方法在执行过程中局部变量的信息。在 Code 属性的属性表中,LocalVariableTable 属性可以按照任意顺序出现。Code 属性中的每个局部变量最多只能有一个 LocalVariableTable 属性。

  • start pc + length 表示这个变量在字节码中的生命周期起始和结束的偏移位置(this 生命周期从头 0 到结尾 )

  • index 就是这个变量在局部变量表中的槽位(槽位可复用)

  • name 就是变量名

  • Descriptor 表示局部变量类型描述

// LocalVariableTable属性表结构:

LocalVariableTable_attribute{
    u2 attribute_name_index;
    u4 attribute_length;
    u2 local_variable_table_length;
    {
        u2 start_pc;
        u2 length;
        u2 name_index;
        u2 descriptor_index;
        u2 index;
    } local_variable_table[local_variable_table_length];
}

7 Signature 属性

Signature 属性是可选的定长属性,位于 ClassFile,field_info 或 method_info 结构的属性表中。在 Java 语言中,任何类、接口、初始化方法或成员的泛型签名如果包含了类型变量(Type Variables)或参数化类型(Parameterized Types),则 Signature 属性会为它记录泛型签名信息。

8 SourceFile 属性

SourceFile 属性结构

类型

名称

数量

含义

u2

attribute_name_index

1

属性名索引

u4

attribute_length

1

属性长度

u2

sourcefile index

1

源码文件素引

可以看到,其长度总是固定的 8 个字节。

9 其他属性

Java 虚拟机中预定义的属性有 20 多个,这里就不一一介绍了,通过上面几个属性的介绍,只要领会其精髓,其他属性的解读也是易如反掌。

四 实战

1 代码

package chapter01.java1;

/**
* 全类名:chapter01.java1.Demo
* 全限定名:chapter01/java1/Demo
*/
public class Demo {
    private int num = 1;

    public int add() {
        num = num + 2;
        return num;
    }
}

2 class 文件解析

class 属性表

3 IDEA 解析

class 属性表

 

上一篇:xml读取


下一篇:paraview计算区域中的平均流速