2.按照指定格式读取class 文件
2.1. class文件示例
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
public class ClassFileTest {
public static final boolean FLAG = false;
public static final byte BYTE = 123;
public static final char X = 'X';
public static final short SHORT = 12345;
public static final int INT = 123456789;
public static final long LONG = 1234567L;
public static final float PI = 3.1415925F;
public static final double E = 2.71828D;
public ClassFileTest() {
}
public static void main(String[] args) {
System.out.println("HelloWorld");
}
}
更详细的请阅读 0.从0开始的手写java虚拟机-class文件示例解读
class file文件格式 : jvms官网
2.2.书写代码
func (self *ClassFile) read(reader *ClassReader) {
self.readAndCheckMagic(reader) //检查class文件格式,0xCAFEBABE
self.readAndCheckVersion(reader) //检查class文件版本
self.constant_pool_count = reader.readUint16() //获取常量池中元素个数
self.cp_info = readConstantPool(self.constant_pool_count, reader) //解析常量池
ConstantPoolInstance = self.cp_info //保存一个常量池示例供外部使用
self.access_flags = reader.readUint16() //获取class文件访问权限
self.this_class = reader.readUint16() //获取当前的class,
self.super_class = reader.readUint16() //获取超类的class,其中java.lang.Object为空
self.interfaces_count = reader.readUint16() //获取接口数量
self.interfaces = reader.readUint16s(self.interfaces_count) //解析接口
self.fields_count = reader.readUint16() //获取字段的数量
self.fields = readMembers(self.fields_count, reader) //读取字段
self.methods_count = reader.readUint16() //获取方法的数量
self.methods = readMembers(self.methods_count, reader) //读取方法,注意此处和获取字段时的方法一致,因为两者的格式一致
self.attributes_count = reader.readUint16() //获取属性的数量
self.attributes = readAttributes(self.attributes_count, reader) //读取属性
}
2.2.1.检查class文件格式,0xCAFEBABE
func (self *ClassFile) readAndCheckMagic(reader *ClassReader) {
magic := reader.readUint32()
if magic != 0xCAFEBABE {
panic("java.lang.ClassFormatError: magic!")
}
}
2.2.2.检查class文件版本
func (self *ClassFile) readAndCheckVersion(reader *ClassReader) {
self.minorVersion = reader.readUint16()
self.majorVersion = reader.readUint16