Class类文件结构

作者: pgydbh | 来源:发表于2018-12-06 17:13 被阅读5次

    引用了

    Class文件结构

    前言

    1.最近在学习关于虚拟机的知识,整理一份比较详细的class文件结构。
    2.翻译class文件就可以称为解释器
    3.你可以使用javap -v Hello.class 命令去查看class类文件结构
    4.可以从你的目标目录和安装目录的rt.jar中读取基本够用的class文件

    读取字节码

    private fun getClassBit(goal: String): ByteArrayBean {
        var result = getFromJar("/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/rt.jar", goal)
        if (result == null) {
            result = getFromFile("/Users/haha/Downloads/", goal)
        }
        return ByteArrayBean(result, 0)
    }
    
    private fun getFromJar(path: String, goal: String): ByteArray? {
        val zipInputStream = ZipInputStream(FileInputStream(path))
        val zipFile = ZipFile(path)
        var zipEntry: ZipEntry?
        while (true) {
            zipEntry = zipInputStream.nextEntry
            if (zipEntry == null) {
                break
            }
            if (zipEntry.name == goal.plus(".class")) {
                return zipFile?.getInputStream(zipEntry).readBytes()
            }
        }
        return null
    }
    
    private fun getFromFile(path: String, goal: String): ByteArray {
        val file = File("$path$goal.class")
        return file.readBytes()
    }
    

    Class类文件结构

    名称 变量 长度/Byte
    魔数 magic 4
    次版本号 minor_version 2
    主版本号 major version 2
    常量数 constant_num 2
    常量池 constant_pool 常量*(constant_num - 1)
    访问标志 access_flags 2
    类索引 this_class 2
    父类索引 super_class 2
    接口数量 interface_num 2
    接口池 interface_pool 接口*(interface_num)
    变量数量 field_num 2
    变量池 field_pool 变量*(field_num)
    方法数量 method_num 2
    方法池 method_pool 方法*(method_num)
    附加属性数量 attribute_num 2
    附加属性池 attribute_pool 附加属性*(attribute_num)

    常量结构

    名称 变量 长度/byte
    类型 type 1
    内容 content 不固定,由下表决定
    类型值 名称 格式 长度/bytes 说明
    1 UTF8 length 2 长度
    Text length 内容
    3 Int 4
    4 Float 4
    5 Long 8
    6 Double 8
    7 Class index 2 指向index位置的utf8常量
    8 String index 2 指向index位置的utf8常量
    9 Fieldref class index 2 指向index位置的class常量
    nameAndType index 2 指向index位置的nameAndType常量
    10 Methodref class index 2 指向index位置的class常量
    nameAndType index 2 指向index位置的nameAndType常量
    11 Interface Methodref class index 2 指向index位置的class常量
    nameAndType index 2 指向index位置的nameAndType常量
    12 NameAndType name index 2 指向index位置的utf8常量
    type index 2 指向index位置的utf8常量

    备注:当常量池出现long时,constant_pool应该跳过一位,例如constant_pool[16]=1280977330748,下一位应该给constant_pool[18]赋值,原因未知,double未测试,测试class文件为String.class

    接口结构

    名称 长度
    Interface Classref Index 2

    备注:接口池存的很简单,只是指向常量池中接口类的索引

    变量结构

    名称 变量 长度/bytes
    访问标志 access_flags 2
    变量名索引 name_index 2
    变量类型索引 descriptor_index 2
    附加属性数量 attribute_num 2
    附加属性池 attribute_pool 附加属性*(attribute_num)

    方法结构

    名称 变量 长度/bytes
    访问标志 access_flags 2
    方法名索引 name_index 2
    方法类型索引 descriptor_index 2
    附加属性数量 attribute_num 2
    附加属性池 attribute_pool 附加属性*(attribute_num)

    附加属性结构

    名称 变量 长度/bytes
    属性名索引 name_index 2
    长度 length 4
    内容 attribute_pool length

    根据name_index指向的属性决定,属性bean可能为不同格式,不同长度

    方法结构-附加属性-Code属性(属于附加属性,包含附加属性)

    名称 变量 长度/bytes
    最大栈深度 stack_length 2
    局部变量表大小 localproperty_num 2
    指令长度 order_length 4
    指令集 order_array order_length
    异常数量 exception_num 2
    异常池 exception_pool 异常属性*exception_num
    附加属性数量 attribute_num 2
    附加属性池 attribute_pool 附加属性*(attribute_num)

    方法结构-附加属性-Code属性-异常属性

    名称 变量 长度/bytes
    起始指令位置 from 2
    结束指令位置 to 2
    目标指令位置 target 2
    异常类型 type 2

    已知附加属性

    属性名 class field method method-code
    Signature * * *
    Code *
    LineNumberTable *
    LocalVariableTable *
    StackMapTable *
    Deprecated *
    RuntimeVisibleAnnotations *
    Exceptions *
    SourceFile *
    InnerClasses *

    类访问标志符

    类访问标志符

    方法访问标志符

    方法访问标志符

    相关文章

      网友评论

        本文标题:Class类文件结构

        本文链接:https://www.haomeiwen.com/subject/pipncqtx.html