现在的位置: 首页 > 综合 > 正文

类文件结构

2018年06月08日 ⁄ 综合 ⁄ 共 1346字 ⁄ 字号 评论关闭

转载请注明出处:http://blog.csdn.net/kai_wei_zhang/article/details/8183164

1、class文件是一组以8位字节为基础单位的二进制流

2、class的结构不像xml等描述语言,由于它没有任何分隔符,故无论是顺序还是数量,都是被严格限定的,哪个字节代表什么含义,长度多少,先后顺序如何,都不允许改变

3、各部分字节结构(只选取一小部分说明)

魔数:用于确定文件类型、身份识别(由于扩展名可以随便地被改动)

类索引、父类索引、接口索引集合:这三项数据用来确定这个类的继承类型。类索引用于确定这个类的全限定名。父类索引只有一个(除了java.lang.Object外)所有类都有父类,故父类索引不为0

字段表集合:字段包括了类级变量或实例变量,但不包括在方法内部声明的变量

方法表集合:Java代码的方法特征签名只包括了方法名称,参数顺序以及参数类型,而字节码的特征签名还包括方法返回值以及受查异常表,故当两个方法只有返回值不用是可以同存于同一个class文件的

属性表集合:Java程序方法体里面的代码经过Javac编译器处理之后,最终变成字节码指令存储在Code属性内

(1)Code属性的结构中包括有max_locals代表局部变量表所需要的存储空间,但并不是方法中有多少局部变量就是它们的总和,是可以重用的,当一个局部变量超出它的作用域时,它所占的空间就可以被其他局部变量用

code_length 虚拟机中限制了一个方法不能长于65535条字节码指令,超过的话Javac会拒绝编译,我们平时不会超过,但是有时复杂的Jsp会超过导致编译失败

(2)this实现原理:Javac编译器在编译的时候把对this关键字的访问转变为对一个普通方法参数的访问,然后在虚拟机调用示例方法时自动传入此参数即可

Exception属性:这里指的是方法描述时在throws关键字后面列举的异常,而try...catch...finally形式的是在code属性中的,注意区别,用throws,throw和try...catch...finally的捕获方式有哪些区别?

LineNumberTable属性

描述源码行号和字节码行号,默认会生成到class文件中,但可以在Javac中使用 -g:none 或 -g:lines控制

影响:如去掉,运行时抛异常,堆栈中将不会显示出错误行号,并且调试无法在掩码中设断点

LocalVariableTable属性

如果取消该属性信息生成,会造成参数名称丢失,IDE可能会以arg0、arg1占位符代替

start_pc和length分别代表局部变量的生命周期开始字节码偏移量以及作用范围覆盖长度,两者结合构成该局部变量在字节码中的作用范围

ConstantValue属性

该属性的作用是通知虚拟机自动为静态变量赋值 int x = 123;和static int x = 123两种是不同的,对非static类型的实例变量的赋值是在实例构造器<init>方法中进行的,而javac对类变量有两种情况:有final修饰的基本类型或String,就生成ConstantValue属性来进行初始化,没有final修饰或非基本类型以及字符串,则选择在<clinit>方法中进行初始化



【上篇】
【下篇】

抱歉!评论已关闭.