• 温故而知新,读懂java字节码


    字节码只有两种结构:无符号数和表。整体结构如下表所示。

    魔术

    魔术是固定的,用十六进制表示为 cafebabe,用以表示这是一个java字节码。

    版本号

    版本号现代只用主版本号,此版本号全部为0. 在jdk12时期,此版本号被用作公测特性申明。

    常量池

    • 只有常量池的计数和序号从1开始,其他重复项的技术和需要还是从0开始的。
    • 常量池中存放两大类常量:字面量和符号引用。
    • 常量池中每一项都是一个表
    • 常量池中的表结构,第一项都是tag,表示表的类型。
    • 局部变量名、方法名、属性名,以及引用外部类方法名、Object上的一些东西,都会直接或间接把名字存到Utf8类型的表上。

    访问标志

    这是一个2字节的标记符,每一位上代表一个含义,如是否为public 、是否为final等等。

    类索引、父类索引和接口索引集合

    • 类索引和接口都是一个u2,表示常量池中的一个constant_class_info类型的表项。
    • 接口索引是一个集合,现有一个u2表示接口数,后面有0-n个u2,表示各接口在常量池中的编号。

    字段表集合

    • 先有一个u2表示字段个数(包括类级变量和实例变量、但不包括局部变量)
    • 后面跟0-n个field_info表。
    • 每个field_info表先有一个u2控制符flag。再有一个u2字段简单名和一个u2字段描述符,都是表示到常量池的索引号。
    • 字段描述表示字段类型,在常量池中。基本类似(int 、void等)用一个大写字母表示;对象类型用L加对象全限定名表示;数组类型使用一个前置的[符号表示;最后面还有一个属性表集合用以防止一些额外信息(如常量字段的值)。
    • 字段表不会有继承的字段。

    方法表集合

    • 结构和字段表集合一样。但有些项的含义解析不一样:控制符flag的每一位含义不一样、在常量池中,描述符的格式是“(参数1类型参数2类型…)返回值”
    • 方法表也不会有继承的方法。
    • 方法体代码在后面的属性表集合中。

    属性表集合

    属性表集合在class文件、字段表、方法表中都可以出现。属性表是最复杂、扩展性最强的表结构。

    • 最开始是一个u2表示属性名,表示属性表的类型,属性表虚拟机最开始只有9中属性,现在有29种。
    • 接着是一个u4表示后面info信息的长度
    • 最后就是Info信息了

    打开一个字节码文件,把各个部分用不同颜色标记起来,就如下图所示

    参考

    https://segmentfault.com/a/1190000037594434

  • 相关阅读:
    [Java]用于将链表变成字符串并在元素之间插入分隔符的有用函数“String.join”
    Sql语法树示例 select username, ismale from userinfo where age > 20 and level > 5 and 1 = 1
    [Java]一段尚未雕琢的分词代码
    day44_Oracle学习笔记_03
    day43_Oracle学习笔记_02
    WinXP系统中的Oracle数据库如何以管理员身份登录
    Oracle 10G安装指导
    20个Linux服务器性能调优技巧
    Linux 上使用 Gmail SMTP 服务器发送邮件通知
    Netdata Linux下性能实时监测工具
  • 原文地址:https://www.cnblogs.com/JMLiu/p/15870298.html
Copyright © 2020-2023  润新知