能看懂的字节码-上

大纲

文章目录

  • 大纲
  • 前言
  • Class文件结构
    • 需要记的
    • Class文件格式
      • 严格限定,不可更改
  • 准备
    • 程序
    • 软件
    • 打开命令行
  • 魔数
    • 概念
    • Class文件的魔数
  • 版本
  • 常量池
    • 范围
    • 有什么
    • 怎么看
  • 最后
  • 下篇预告

前言


我的所有文章同步更新与Github–Java-Notes,想了解JVM,HashMap源码分析,spring相关,剑指offer题解(Java版),可以点个star。可以看我的github主页,每天都在更新哟。

邀请您跟我一同完成 repo


上篇文章通过Java的跨平台性引出了字节码文件,这篇文章就是解读字节码文件到底存了哪些东西

这个分析真的很难懂也很绕,不过如果你掌握了字节码的分析方法,怎么看字节码,那么就挺容易看懂的,希望你有耐心看下去。因为我觉得这应该算是非常详细而且简单的分析。我尽量做到详细解读,书上很多隐藏的没说的也尽量给你们讲出来,毕竟对于初学者确实有些坑会卡很久

可以和《深入理解Java虚拟机》第二版一起看,不过书上的例子和我实际运行的不一样,你们看到的应该也是我这种,但是并不影响我们找到查看字节码的方法。毕竟方法是互通的

这里说的字节码文件和Class文件是一个东西,文章中可能混用,请一定记住

Class文件结构

任何一个Class文件都对应着唯一一个类或接口的定义信息,但反过来说,类或接口并不一定都得定义在文件里(譬如类或接口也可以通过类加载器直接生成)。(如果不懂这个也不必记)

需要记的

  • Class文件是一组 8位字节为基础的二进制流(后面会介绍),各个数据之间排列非常紧凑

  • Class文件采用类似于C语言结构体伪结构来存储数据,只有两种数据类型

    • 无符
      • 无符 数属于基本的数据类型,以u1,u2,u4,u8来表示一个字节,两个字节,以此类推
      • 是复合结构。可能由多个无符 数或者其他表作为数据项构成的类型,习惯性的以”_info”结尾
    • 你可以把整个Class文件看成是一张表

Class文件格式

class文件一共只由这么多个东西组成

打开命令行

  • 使用Javac命令,把相应程序编译成Class文件

    • 使用刚刚的软件打开Class文件

    **就像是你给狗起了个人名,难道他就是人了吗你只有改了他的DNA,他才有可能成为人。名字就对应后缀名,DNA就对应魔数

    Class文件的魔数

    ,这个魔数是不是很浪漫有想到和Java的名字相关(Java也是一种咖啡)这个魔数是在 Java还在叫Oak的时候就已经确定了下来,或许后面改名Java的时候参考了魔数

    版本

    紧接着魔数的后面的两个数据是版本 ,分别都为u2类型,也就是要看2个字节。

    有什么

    常量池中主要存放两大类:

    • 字面量
      • 文本字符串
      • 声明为final的常量值
      • 等….
    • 符 引用
      • 类和结构的全限定名
      • 字段的名称和描述符
      • 方法的名称和描述符

    怎么看

    还记得那个表吗

    在看字节码之前,我们得现弄明白常量池中都有哪些项目类型,一共有14个(JDK1.7,1.8之后增加了没有我也不知道,不过不影响我们阅读和理解字节码)

    他们的共同特点是,表开始的第一位是一个u1类型的标志位(tag)

    • 我们看到第一个是0x0A,由他们的特征知道他是标志位(不清楚的,你可能忘了或者没看到我图片上面的一句话),

    • 那么我们就转换成十进制,就是 10。

    • 查看图片,找到标志位是10 的那个常量表。

    由于已经确定了数据的表结构,所以他并没有tag,所以0x0004就表示后面的index,即指向全限定名的常量项目的索引,而他指向第四个常量。(我们现在还没分析到第四个常量,但是我们可以通过之前命令行里的内容找到第四个常量代表啥)

    能看懂的字节码-上

    所以它实际上是指向类的全限定名-。

    我们也可以通过 javap -verbose 这个来验证我们刚刚翻译过来的字节码到底对不对,我们看到,确实没有问题。

    我们再看他的第三个数据项,0x000F,再根据刚刚的方法,我们找到 常量池中第15个常量为 NameAndType类型,并且指向第7和第8 个常量。

    后面的翻译方法跟这个一样,我就不再啰嗦了你也可以根据我说的方法一一去验证,直到把常量池中的全部翻译完。

    最后

    如果你想看懂字节码,知道他们代表什么意思,那你最好反复看下我的这个文章,跟我我的方法一一验证一下,弄懂该怎么去看字节码的数据结构体。因为后面的访问标志、类索引和接口索引、字段表集合等等,Class文件的内容都是要采用这种方法翻译。

    想要看剩下的都是哪些内容,可以看我的下篇,能看懂的字节码-下。因为这篇主要是讲如何看懂字节码的方法,该用到哪些工具,怎么验证自己翻译的对不对。

    下篇预告

    字节码中的:

    • 访问标志

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

    • 字段表结合

    • 方法表集合

    • 属性表集合

    文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树首页概览92526 人正在系统学习中

    声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年4月9日
下一篇 2019年4月9日

相关推荐