java字节码详解

一、整体结构

java字节码详解_第1张图片

二、详解

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

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

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

1.魔数变量与class的版本

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

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

java字节码详解_第3张图片

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



2.常量池

常量池中的每一项都是一个表,每个表又是一种类型然后,这些类型又有它们自己的结构。一般第一位都是标志位,标示这个表是个什么类型的表。如下图:
java字节码详解_第4张图片
java字节码详解_第5张图片
java字节码详解_第6张图片
类似上图:我们来找一下,类的全限定名。
java字节码详解_第7张图片
从图中,偏移量(图中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虚拟机这本书的,它也没有这样去做,没有意义,关键是这个过程。我们来总结过程。

你可能感兴趣的:(java字节码详解)