JAVA字节码文件之第四篇(方法分析)
一、Methods 方法字节码结构
Methods 字节码结构:
Methods num:占两byte,Methods 的具体内存占n个byte
方法中每个属性都是Attribute_info,Attribute_info的结构:
1、attribute_name_index:属性名的索引
2、attribute_length:表示attribute所包含的字节数,不包含attribute_name_index和attribute_length字段
3、max_stack:表示这个方法运行的任何时刻所能到达的操作数栈的最大深度。
4、max_locals:表示方法执行期间创建的局部变量的数目,包含用来表示传入的参数的局部变量。
5、code_length:表示该方法所包含的字节码的字节数以及具体的指令码,具体字节码即是该方法被调用时,虚拟机执行的字节码
6、code[code_length]:虚拟机运行时具体的字节
7、exception_table_length:异常表的长度
8、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时,表示处理所有的异常
9、Attribute_count:
10、Attribute_info Attributes[Attribute_count]
二、Methods 字节码分析
上一节 JAVA字节码文件之第三篇(访问标识) 我们分析到了 Fields(属性)字节码 就是图中红色箭头的位置。
1、Methods num(3) : 占两个byte 00 03,即该类有三个方法。
第一个方法:
Access_Flags(1):占2个byte 00 01;根据 上一节JAVA字节码文件之第三篇(访问标识) 可知
name_index(7):占 2个字节 00 07;索引为7,对应常量池中的#7, 由<init>可知他是一个构造方法
descriptor_index(8):占两个byte,00 08,对应常量池的#8,由()V可知这是一个无参数的(构造)方法
attribute_info结构
attributes_count(1):占两个byte 00 01,表示该方法第一个属性(这里的属性并不是我们常说的类的属性,方法的参数,而是编译器生成的属性)
1、Attribute_name_index(9):方法的第一个属性名字,占两个byte,对应常量池中的#9,code就是该方法的第一个属性
2、Attribute_length(0x38=56):占4个byte 00 00 00 38,表明该属性code的长度是56个字节。所以整个Attribute_info 对应字节如下图
3、max_stack(2):占2个byte 00 02 操作数栈的最大深度是2
4、max_locals(1):占两个byte 00 01
5、code_length(10) :占四个字节 00 00 00 0A ,
6、code[code_length]:占 code_length 个byte 即 10个byte ,2A B7 00 01 2A 04 B5 00 02 B1 ;表明该方法在执行时的具体指令;
这些十六进制指令怎么与 图片中的助记符关联的,参考该 网站 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n
例如:aload_0=2A
invokespecial=B7 , 之后的 00 01是他的参数,指向常量池中的#1
父类的构造方法
iconst_1=4
putfield=B5 ,后两个byte 是 参数 00 02,对应常量池的#2
就是给属性赋值 即 int num=1
return = B1 ,构造方法返回void
7、exception_table_length(0): 占两个byte 00 00 ,所以默认的构造器不抛出异常
8、exception_table_info:由于exception_table_length =0 ,所以该部分内容为空
9、Attribute_count (2): 占两个byte 00 02 ,即构造器的Code属性有两个扩展属性
10、Attribute_info[Attribute_count] : 00 0A ,0A=10 ,第一个扩展属性的索引=10,即常量池的#10
11、LineNumberTable 分析
Attribute_length : 占4个byte,00 00 00 0A;0X0A=10,所以00 02 00 00 00 08 00 04 00 09 是LineNumberTable 的具体指令;
前两个字节 00 02 表示 有两对映射关系,00 00 对应 00 08 ,08对应常量池的#8 ;00 04 对应 00 09 ,对应常量池的#9
12、第二个扩展属性 00 0B,0x0B=11 ,对应常量池的#11
Attribute_length :占四个字节 00 00 00 0C,对应的 LocalVariableTable 的内容是 12 个字节 ,即 00 01 00 00 00 0A 00 0C 00 0D 00 00 。
局部变量的格式:00 01
开始位置 00 00
结束位置 00 0A(0A=10)
索引是 00
局部变量对应常量池的位置0C(C=12)
当前局部变量的描述00 0D ,对应常量池的#13
最后的00 00 是一个校验符,没有具体的逻辑含义。
至从第一个方法分析完毕。
三、LineNumberTable
LineNumberTable 属性表存放方法的行号信息 ;属于调试信息,不是运行时必需的。在使用javac编译器编译Java程序时,默认会在class文件中生成这些信息。可以使用javac提供的-g:none选项来关闭该信息的生成
四、LocalVariableTable:列出了所有栈帧中的局部变量
LineNumberTable
JAVA字节码文件之第四篇(方法分析)的更多相关文章
- JAVA字节码文件之第三篇(访问标识)
一.Access Flags 访问标志 访问标志信息包括该 Class 文件是类还是接口,是否被定义成 public 或者 abstract , 如果是类,是否被声明成 final. 访问标志表 二. ...
- JAVA字节码文件之结构
开发工具:IEDA.JDK1.8.WinHex 一.字节码文件结构 源代码 package com.jalja.java.bytecode; /** * @Auther: XL * @Date: 20 ...
- JAVA字节码文件之常量池
一.常量池的内容 一个java类中定义的很多信息都是由常量池来维护和描述的,可以将常量池看作是class文件的资源仓库,比如java类中定义的方法与变量信息.常量池中主要存储两类常量:字面量(文本字符 ...
- 【JVM故事】一个Java字节码文件的诞生记
万字长文,完全虚构. (一) 组里来了个实习生,李大胖面完之后,觉得水平一般,但还是留了下来,为什么呢?各自猜去吧. 李大胖也在心里开导自己,学生嘛,不能要求太高,只要肯上进,慢慢来.就称呼为小白吧. ...
- [置顶] Java字节码文件剖析
Java为什么能够支持跨平台,其实关键就是在于其*.class字节码文件,因为*.class字节码文件有一个统一标准的规范,里面是JVM运行的时需要的相关指令,各家的JVM必须能够解释编译执行标准字节 ...
- 命令行中运行Java字节码文件提示找不到或无法加载主类的问题
测试类在命令行操作,编译通过,运行时,提示 错误: 找不到或无法加载主类 java类 package com.company.schoolExercise; public class test7_3_ ...
- 【java】查看Java字节码文件内容的方法+使用javap找不到类 解决方法
研究synchronized底层实现,涉及到查看java字节码的需要 前提是,你的PC已经成功安装了JDK并别配置了环境变量. ==========查看方法========= 一.javap查看简约字 ...
- java字节码文件指令集
网上找的没有指令码这列 自己把它加上 更方便查阅 指令从0x00-0xc9 没有0xba 常量入栈指令 指令码 操作码(助记符) 操作数 描述(栈指操作数栈) 0x01 aconst_null nu ...
- JAVA反射机制_获取字节码文件对象
是在运行状态中,对于任意一个类 (class文件),都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性: 这种动态获取的信息以及动态调用对象的方法的功能称为java语 ...
随机推荐
- 使用Spring Cloud Gateway保护反应式微服务(二)
抽丝剥茧,细说架构那些事——[优锐课] 接着上篇文章:使用Spring Cloud Gateway保护反应式微服务(一) 我们继续~ 将Spring Cloud Gateway与反应式微服务一起使用 ...
- Window Server 2019 配置篇(8)- 利用MDT定制自动加入域的脚本
我们要更改我们的镜像文件,使得自动安装完成后,计算机已经自动在域中 删除在WDS-server上做的自动部署,我们在上面安装一下MDT和ADK文件,这两个文件如果需要的话可以评论,我会在随后上传 之后 ...
- 201706 gem 'rails-erd'生成Model关系图
[工具]一张图理清各个model之间关系 安装 Graphviz 2.22+: 终端机中执行 brew install graphviz Gemfile中添加 gem 'rails-erd' 终端机中 ...
- 从植发AI看智能手术机器人的国产化之路
在工作和生活的双重压力下,很多80后乃至90后的青年都"光荣"地加入了"脱发一族".为了拯救发际线或是不变成"地中海",很多人从此走上了寻医 ...
- postProcessBeanFactory方法源码跟踪
看这篇文章之前可以先了解之前的跟踪流程,https://www.jianshu.com/p/4934233f0ead 代码过宽,可以shift + 鼠标滚轮 左右滑动查看 AbstractApplic ...
- java.jvm调优
_amazing~ 基本: 整理:
- java中数组输出的方式
方式1:遍历输出 public class Main { public static void main(String[] args) { int[] ns = { 1, 4, 9, 16, 25 } ...
- 玩个JAVA爬虫,没想玩大
想玩个爬虫,爬些数据玩玩,不成想把自己玩“进去”了 想爬这个新浪的股票 大额交易页面 本以为用 HttpClient 直接爬链接,结果发现这个页面中,翻页数据压根就是动态赋值的,根本没有,那我根本无法 ...
- SpringBoot-集成通用mapper
SpringBoot-集成通用mapper SpringBoot-集成通用mapper 我们在SpringBoot中整合了MyBatis,但是大量重复的增删改查还是很头疼的问题,MyBatis也给 ...
- 关于torchvision.models中VGG的笔记
VGG 主要有两种结构,分别是 VGG16 和 VGG19,两者并没有本质上的区别,只是网络深度不一样. 对于给定的感受野,采用堆积的小卷积核是优于采用大的卷积核的,因为多层非线性层可以增加网络深度来 ...