类加载的几个阶段中,在读取类文件之后,就是类文件的解析阶段。本文讲的只是将类文件解析成结构化的形式,类解析阶段的另一部分--字段和方法的静态链接放到后面再讲。
使用ClassFile来定义class 文件的格式,具体属性如下。class文件都以魔数CAFEBABE开头,用以标识这是一个class文件。还有类的访问控制,类名,父类名以及类的方法和类的属性等。constantPool保存了类的所有字面量(字符串,double,long,int),其他地方用到这些值时都是根据索引到常量池中取。如类名就是只保存了类名在常量池中的索引,用到的时候到常量池中找,而不是直接存类名这个字符串。attributes可以说是一个大杂烩,主要是类的一些附加属性,如类源文件的名称。
type ClassFile struct {
classReader *reader.ClassReader
// magic uint32
minorVersion uint16 //版本号
majorVersion uint16
constantPool *constant_info.ConstantPool
accessFlags uint16 //访问标志
thisClass uint16 //类名的索引
superClass uint16 //超类索引
interfaces []uint16
fields []*FieldInfo //字段
methods []*MethodInfo //方法
attributes []attribute_info.AttributeInfo
}
类文件涉及到很多字节流的读取操作,所以用ClassReader封装了一些字节流读取操作
type ClassReader struct {
Data []byte
}
func (this *ClassReader) ReadUint8() uint8 {
val := this.Data[0]
this.Data = this.Data[1:]
return val
}
func (this *ClassReader) ReadUint16() uint16 {
val := binary.BigEndian.Uint16(this.Data)
this.Data = this.Data[2:]
return val
}
func (this *ClassReader) ReadUint32() uint32 {
val := binary.BigEndian.Uint32(this.Data)
this.Data = this.Data[4:]
return val
}
func (this *ClassReader) ReadUi