电子说
1.「LocalVariableTable」
❝用于描述局部变量表中的变量与JAVA代码中定义变量之间的关系,同样也可以选择不生成该属性
❞
❝用处:当编写代码引用到这个方法时,参数可以直接显示变量名和类型,如果没有该属性,就用arg0,arg1代替;调试信息的时候可以根据参数变量名明确语义。
❞
2.「LocalVariableTypeTable」
❝引入泛型后加入的属性,结构和LocalVariableTable相似,将原先用于描述字段描述符的descriptor_index替换成了描述字段的特征签名(Signature)。
❞
❝对于非泛型变量,特征签名和描述符是一致的,但是对于泛型来说,由于泛型参数类型的擦除,描述符不能够描述泛型类型,因此定义了该属性来完成泛型的描述。
❞
结构:
「变量初始化,赋值时机:」 位于该属性结构中的常量将会在类加载的准备阶段就会初始化并且赋值;
其他的静态变量在这个阶段只是会被初始化然后赋默认值,如果静态变量设置了final关键字,那么就是第一种情况会对变量进行赋值;
对于实例变量(非静态变量)的赋值是在实例构造器《init》中。
「该结构中存放的字段是:」
「《Java虚拟机规范》中规定该属性结构中存放的必须是静态的字段,而对于javac编译器来说还需要满足final关键字的修饰,因此经过javac编译器编译后的该属性中存放的字段必须是static并且是final的。」
❝通知虚拟机自动为静态变量赋值(上面那句话)。该属性中只能存放基本类型和String,因为该属性的属性值
❞
结构:
❝这两项属性有点特殊,不携带任何属性值,出现这两个属性的目的只是为了标识,这两个属性只有存在或不存在。
❞
2.「Synthetic属性」
该属性用于表示字段或者方法是编译器自己添加的,不是代码中的。也可以通过设置访问标志ACC_SYNTHETIC标志位生成该项属性。
结构:两者都一样,不携带任何属性值。只是用于标识
「该属性位于Code属性的属性表中」
❝用处:在类加载阶段的验证阶段使用该属性,代替以前耗性能的基于数据流分析的类型推导验证器(有了该属性之后就不用类型推导了,可以直接判断类型是不是符合要求,之后单独写类加载阶段进行分析)
❞
❝之前验证阶段是基于数据流来进行分析推导出操作数栈和本地变量表操作的类型是否一致等(比如istore需要将操作数栈的数据保存到本地变量表中,但是取出的数据类型不是int就会发生问题),现在基于该项属性可以不用推导
❞
结构:「一个Code属性最多只能有一个StackMapTable属性」
「用于记录方法的各个形参名称和信息」
方法参数属性,位于class中的属性表中。之前说过这部分是存储在局部变量表中的,因为方法中有方法体code属性,而code中需要有局部变量表属性代表这个方法中的变量存储。
但是为什么还要单独抽出一个属性放在class中呢?
大家想想没有code就没有局部变量表,没有局部变量表是不是就不能存储方法参数了;你看接口中他有方法吧但是呢他其实没有方法提code所以它的方法参数往哪放呢?往他借口的属性表集合中放,也就是与code同级。这样的话我接口里可以直接获得方法参数通过这个属性;而对于正常的方法也就是有方法体的代码可以从code中的局部变量表中拿。
数据结构:1.首先说明他是什么,我是一个方法参数类型 2.我说明我存储的时候数据有多长(多少字节),为了切割按照这个就可以正确读取对应的数据;但是如果这个属性中还用到了其他的数据结构(属性),那么就是这个属性的个数了
3.对于没有再次用到其他属性来描述的属性直接使用定长数据即可;但是对于有用到其他属性来描述这个属性的话,则后面是对应的属性一个一个排开,然后每个属性如果是定长的话则不需要通过长度来说明所占字节,然后这个属性中存储的第一个永远是他是什么也就是名字,然后再是对应的值
不断使用这种结构来描述一个完整的class结构
结构:
全部0条评论
快来发表一下你的评论吧 !