字节码

作者: 你值得拥有更好的12138 | 来源:发表于2019-01-04 22:17 被阅读0次

    一、整体结构

    class结构图

    二、详解

    *首先要说下class文件的定义:

    1. 8位字节为基础单位的二进制流。
    2. 有着严格的顺序,中间是没有空隙,即没有多余的数据。
    3. 如果超过8个字节,以高位在前的方式分割为若干个8位字节。
    4. 整体结构是由一个无符号数+一个表,表中有指向其他表的索引,直到找到最后的值,这个值大部分的时候终点会在常量池中。
    5. 无符号数分为u1,u2,u3,u4,分别表示是一个字节,两个字节。。。。。


      这里写图片描述

    如果你使用16进制的工具打开字节码文件,内容就是以16进制为基础。

    1.魔数变量与class的版本

    从图中我们可以看出,前4个十六进,虚拟机遇到这个单词时,就知道是字节码文件了。


    紧接着后面4个字节,就是class的版本,前两个是次版本号,后两个是主版本号。版本号的对应是这样的:

    这里写图片描述

    其实到这里,就有了一个整体的思路了:字节码文件其实也就是一种语法,它同样是可以用来写程序像java一样。其实可以看作一种语言。如果你足够牛逼的话,你可以直接写字节码给虚拟机执行是完全没有问题的。动态代理,其实也就是这样做的,在代码运行过程中去代理的。但是这样太困难了,所以我们就使用了java来写程序,而且字节码的出现其实是为了跨平台的。


    2.常量池

    常量池中的每一项都是一个表,每个表又是一种类型然后,这些类型又有它们自己的结构。一般第一位都是标志位,标示这个表是个什么类型的表。如下图:

    这里写图片描述
    这里写图片描述
    这里写图片描述
    类似上图:我们来找一下,类的全限定名。
    这里写图片描述
    从图中,偏移量(图中offset)到7的位置我们已经解析了,是魔数和版本号,然后8,9的位置是表示常量池的常量的个数,0016为22,但是常量池的计数从1开始,所以21个变量。然后继续后个字节是07,从这里开始常量池的内容就开始了,前面说过一般第一个字节就是标识,然后去6-3表中找07是什么类型,一看class_info。


    发现6-4表就是这个类型,从表中我们又知道这类型由两个类型构成,tag和nameindex组成,然后他们是u1,u2,说明他们分别是一个字节,两个字节,然后再去看图6-4,这07就class_info的tag字段,然后向后两个字节,是00 02,说明nameinex的值是2;

    这个nameIndex在很多表中,都存在,它的含义是在常量池中的第几个常量,目前这个是第一个常量,所以接着后面找。第一个字节是01对应utf_info即字符串,然后看表6-5,u2 --length表示长度,00 1D,长度为29,byte就是字符串内容了,后面29个字节的结果如图。

    好了,上面的过程就是整个字节码的结构和查找流程,后面的什么字段表,方法表都是这样去做,只是我们不能把字节码的所有的表类型列出来,我是看深入理解java虚拟机这本书的,它也没有这样去做,没有意义,关键是这个过程。我们来总结过程。

    相关文章

      网友评论

          本文标题:字节码

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