方法表:

在上一次咱们已经分析到了字段信息了,如下:

紧接着就是方法相关的信息了:

而它展开之后的结构为:

所以往后数2个字节,看一下方法的总数:

3个方法,可咱们只定义了两个方法呀:

因为编译器会为我们生成一个默认的构造方法,所以就3个了,那每个方法的具体信息是啥呢?它是一个method_info类型的,如下:

也就是方法表,当然也有它自己的一个结构,下面来看一下:

  • access_flags:占用两个字节,表示访问标记。
  • name_index:占用两个字节,名字索引,指向的是常量池。
  • descriptor_index:占用两个字节,描述索引,指赂的是常量池。
  • attributes_count:占用两个字节,属性个数,如果为0,则下面的属性表就不显示了。
  • attributes::属性表。

用结构形式来表示:

那按照上面的表先来看第一个方法的访问标记,往后读两个字节:

查看下访问修饰符表,对应于:

表示是一个public的方法,接下来两个字节则表示方法名字索引,走着:

对应常量池:

再往下二个字节则表示描述符索引:

对应常量池:

说明该方法是一个默认构造方法。从javap -verbose中也能对应上:

属性表:

接下来二个字节为属性个数:

表示有一个属性,所以属性表中的个数也为1,而属性表是attribute_info类型,很显然也有它自己的结构,那长啥样呢?

  • attribute_name_index:占2个字节,表示属性名字的索引,指向常量池。
  • attribute_length:占4个字节,表示属性的长度。
  • info[attribute_length]:占1个字节,表示具体的信息。

依照上面的顺序,先数2个字节:

对应常量池:

其实在javap -verbose中也能看到每个方法都有一个Code字样,如下:

Constant pool:#1 = Methodref          #4.#20         // java/lang/Object."<init>":()V#2 = Fieldref           #3.#21         // com/jvm/bytecode/MyTest1.a:I#3 = Class              #22            // com/jvm/bytecode/MyTest1#4 = Class              #23            // java/lang/Object#5 = Utf8               a#6 = Utf8               I#7 = Utf8               <init>#8 = Utf8               ()V#9 = Utf8               Code#10 = Utf8               LineNumberTable#11 = Utf8               LocalVariableTable#12 = Utf8               this#13 = Utf8               Lcom/jvm/bytecode/MyTest1;#14 = Utf8               getA#15 = Utf8               ()I#16 = Utf8               setA#17 = Utf8               (I)V#18 = Utf8               SourceFile#19 = Utf8               MyTest1.java#20 = NameAndType        #7:#8          // "<init>":()V#21 = NameAndType        #5:#6          // a:I#22 = Utf8               com/jvm/bytecode/MyTest1#23 = Utf8               java/lang/Object
{public com.jvm.bytecode.MyTest1();descriptor: ()Vflags: ACC_PUBLICCode:stack=2, locals=1, args_size=10: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: aload_05: iconst_16: putfield      #2                  // Field a:I9: returnLineNumberTable:line 3: 0line 4: 4LocalVariableTable:Start  Length  Slot  Name   Signature0      10     0  this   Lcom/jvm/bytecode/MyTest1;public int getA();descriptor: ()Iflags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: getfield      #2                  // Field a:I4: ireturnLineNumberTable:line 7: 0LocalVariableTable:Start  Length  Slot  Name   Signature0       5     0  this   Lcom/jvm/bytecode/MyTest1;public void setA(int);descriptor: (I)Vflags: ACC_PUBLICCode:stack=2, locals=2, args_size=20: aload_01: iload_12: putfield      #2                  // Field a:I5: returnLineNumberTable:line 11: 0line 12: 5LocalVariableTable:Start  Length  Slot  Name   Signature0       6     0  this   Lcom/jvm/bytecode/MyTest1;0       6     1     a   I
}
SourceFile: "MyTest1.java"

那它表示啥意思呢?其实是表示方法执行的代码,指的是:

当然啦在字节码文件中不可能是跟源文件中看到的一样,而是通过了一些助记符进行了处理,如下:

这个在未来进行详细学习的,好,继续来分析属性,接下来4个字节表示属性的长度,如下:

说明属性的长度为56,然后最后一个字节表示info信息,也就是code的具体信息,这块是比较复杂的,下面先来了解一些理论:

  • JVM预定义了部分attribute,但是编译器自己也可以实现自己的attribute写入class文件里,供运行时使用。
  • 不同的attribute通过attribute_name_index来区分。

其中JVM预定义的attribute为如下表:

Code结构:

这部分东东是比较多的,这次只先对其结构有个初步了解既可,它的作用是保存该方法的结构,如所对应的字节码:

  • attribute_length表示attribute所包含的字节数,不包含attribute_name_index和attribute_length字段。
  • max_stack表示这个方法运行的任何时刻所能达到的操作数栈的最大深度。
  • max_locals表示方法执行期间创建的局部变量的数目,包含用来表示传入的参数的局部变量。
  • code_length表法该方法所包含的字节码的字节数以及具体的指令码。
  • 具体的字节码既是该方法被调用时,虚拟机所执行的字节码。
  • exception_table:这里存放的是处理异常的信息。
  • 第一个exception_table表项由start_pc、end_pc、handler_pc、catch_type组成。
  • start_pc和end_pc表示在code数组中的从start_pc到end_pc处(包含start_pc,不包含end_pc)的指令抛出的异常会由这个表项来处理。
  • handler_pc表示处理异常的代码的开始处。catch_type表示会被处理的异常类型,它指向常量池里的一个异常类。当catch_type为0时,表示处理所有的异常。

这么多陌生的字段,直接晕掉,木要着急,先有个大概了解,在未来学习中会吃透它的,好,先来回到字节码中继续分析,其中code中属性的长度为56:

接下来2个字节表示max_stack:

再接下来2个字节表示max_locals:

对应javap -verbose:

接下来4个字节表示code的长度:

code_length=10,而此时发现在javap -verbose中貌似木有找到对应的:

那接下来的分析没有了参照就不知道我们自己分析的对不对了,对于学习效果会大打折扣了,此时就得借助于另外一个工具来参照了,该工具为jclasslib,gitbub地址:https://github.com/ingokegel/jclasslib,它显示的信息就会比javap -verbose要详细很多,访问一下官网:

它包含独立的软件和IntelliJ IDEA插件化的方式,所以都装一下,先下载mac安装包:

具体安装就不概述了,装好之后用它来打开我们的字节码文件既可,长这样:

同时可以给IDE装上插件,更加便于分析,如下:

安装好之后,直接就可以在当前打开的java文件中执行这个菜单选项既可:

看到的效果跟独立的软件看到的是一样的,好,下面来用这个新工具来瞅一眼看到的信息:

对比下javap -verbose:

差不多,不过jclasslib工具可以看到JDK的版本,接下来就是常量池:

但实际是只有23个,展开看一下:

对于javap -versbose:

明显要丰富许多,继续往下看:

其中是可以直接点击链到对应的常量池的,如下:

接着就是常量池的信息了:

展开之后,索引都能链接上去,非常之方便:

接着就是接口信息,目前木有接口:

然后就到了字段信息了,目前只有一个字段:

然后再是方法信息,有三个方法:

点击其中一个看一下:

有code信息:

跟javap -versbose是对应上的:

最后是附加信息:

LineNumberTable:这个属性用来表示code数组中的字节码和Java代码行数之间的关系。这个属性可以用来在调试的时候定位代码执行的行数。比如说程序抛异常了,而程序执行的是字节码文件,怎么我们就能看到具体报错在源码中的行数呢,其实就是通过该信息做到的。

而它的结构体为:

跟javap -verbose中是能对应上的:

最后则是类的属性了:

可见jclasslib的结构跟咱们理论上看到的是一模一样的,所以有了它也能让我们在未来学习code这块的结构更加清晰,这是javap -verbose不能达到的。

转载于:https://www.cnblogs.com/webor2006/p/9459681.html

Java字节码方法表与属性表深度剖析相关推荐

  1. 【Java 虚拟机原理】Class 字节码二进制文件分析 六 ( 属性类型 | Code 属性 | 属性名称索引 | 属性长度 | 操作数栈最大深度 | 局部变量存储空间 | 字节码长度 )

    文章目录 前言 一.属性类型 二.Code 属性表数据结构 三.属性名称索引 四.属性长度 五.操作数栈最大深度 六.局部变量存储空间 七.字节码长度 八.存储字节码指令的一系列字节流 前言 上一篇博 ...

  2. Java字节码角度分析方法调用 ——提升硬实力7

    在前面的文章中,有详细地介绍java字节码相关的知识,有兴趣的可以提前了解一下. 1.Java字节码的一段旅行经历--提升硬实力1 2.Java字节码角度分析a++ --提升硬实力2 3.Java字节 ...

  3. java 字节码查看_一种查看java字节码时显示方法调用关系图的方法与流程

    本发明涉及一种代码逻辑分析方法,具体涉及一种查看java字节码时显示方法调用关系图的方法. 背景技术: 目前软件反编译领域有不少对可执行文件进行反编译的工具如IDA,也有对Java代码生成的中间码文件 ...

  4. 如何阅读JAVA 字节码(一)

      在阅读JAVA字节码以前,需要回忆一下JVM的结构:   Java字节码的信息主要在Java栈中间体现,下图来自网络,描述了java栈的基本结构:   值得注意的是方法区,在Java虚拟机中,方法 ...

  5. 干货!Java字节码增强探秘

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"加群"获取公众号专属群聊入口 来源:美团技术团队 1. 字节码 1.1 什么是字节码? ...

  6. java字节码忍者禁术

    2019独角兽企业重金招聘Python工程师标准>>> Java语言本身是由Java语言规格说明(JLS)所定义的,而Java虚拟机的可执行字节码则是由一个完全独立的标准,即Java ...

  7. idea如何反编译字节码指令_美团点评:Java字节码增强技术,线上问题诊断利器...

    作者简介:泽恩,美团到店住宿业务研发团队工程师.文章转载于公众号:美团技术团队 1. 字节码 1.1 什么是字节码? Java之所以可以"一次编译,到处运行",一是因为JVM针对各 ...

  8. 这一次,彻底弄懂 Java 字节码文件!

    作者 | 东升的思考 责编 | Elle 不啰嗦,直接从最最简单的一段Java源代码开启Java整体字节码分析之旅. Java 源码文件 package com.dskj.jvm.bytecode; ...

  9. 从一个class文件深入理解Java字节码结构

    前言 我们都知道,Java程序最终是转换成class文件执行在虚拟机上的,那么class文件是个怎样的结构,虚拟机又是如何处理去执行class文件里面的内容呢,这篇文章带你深入理解Java字节码中的结 ...

最新文章

  1. Java 对象初始化的过程介绍
  2. Antenna Placement--POJ 3020
  3. java 接口 实现和继承关系
  4. TCL系列 - incr命令
  5. SSL certificate problem: unable to get local issuer certificate
  6. 小程序--计算正负数个数
  7. 一步步实现SDDC-vSphere Auto Deploy的妙用
  8. Codeforces 319C DP 斜率优化
  9. 小白用python处理excel文件-Python读、写Excel文件(三种模块三种方式,小白也可学会)...
  10. python中文版免费下载-Python IDLE汉化版下载
  11. 数据结构串的基本操作及KMP算法
  12. AJAX做一个动态进度条
  13. 对TensorFlow中tf.nn.softmax()函数机器损失函数的理解
  14. 软考高项(信息系统项目管理师)计算题公式汇总
  15. 【HDU1411】四面体的体积公式
  16. 敏捷开发 角色英文简称
  17. ismart软件英语期末测试,iSmart APP
  18. 在latex中设置表格背景色
  19. php 苹果内购支付
  20. Python自动化运行合成大西瓜|附小游戏地址

热门文章

  1. 树莓派Linux内核源码配置、编译、挂载(boot/kernal/根文件)、开启新内核
  2. android自动软键盘,Android自定义软键盘
  3. 从文件中读出数据显示在表格中_玩转表格:如何在Word表格中进行数据计算?...
  4. ccxprocess可以禁用么_提效 | 5G时代网站还需要加速么?
  5. java虚拟机栈基本内容
  6. 威斯康星大学计算机专业找工作,威斯康星麦迪逊大学计算机申请条件有哪些?...
  7. discuz修改用户uid_你知道Linux中的UID和GID的含义吗
  8. U盘拷贝文件很慢?稍微改变一下使用方式,传输速度就快了6倍
  9. IDEA中安装配置Jrebel热部署插件用法笔记
  10. 操作系统基础:计算机作业管理知识笔记