一、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字节码文件之第四篇(方法分析)的更多相关文章

  1. JAVA字节码文件之第三篇(访问标识)

    一.Access Flags 访问标志 访问标志信息包括该 Class 文件是类还是接口,是否被定义成 public 或者 abstract , 如果是类,是否被声明成 final. 访问标志表 二. ...

  2. JAVA字节码文件之结构

    开发工具:IEDA.JDK1.8.WinHex 一.字节码文件结构 源代码 package com.jalja.java.bytecode; /** * @Auther: XL * @Date: 20 ...

  3. JAVA字节码文件之常量池

    一.常量池的内容 一个java类中定义的很多信息都是由常量池来维护和描述的,可以将常量池看作是class文件的资源仓库,比如java类中定义的方法与变量信息.常量池中主要存储两类常量:字面量(文本字符 ...

  4. 【JVM故事】一个Java字节码文件的诞生记

    万字长文,完全虚构. (一) 组里来了个实习生,李大胖面完之后,觉得水平一般,但还是留了下来,为什么呢?各自猜去吧. 李大胖也在心里开导自己,学生嘛,不能要求太高,只要肯上进,慢慢来.就称呼为小白吧. ...

  5. [置顶] Java字节码文件剖析

    Java为什么能够支持跨平台,其实关键就是在于其*.class字节码文件,因为*.class字节码文件有一个统一标准的规范,里面是JVM运行的时需要的相关指令,各家的JVM必须能够解释编译执行标准字节 ...

  6. 命令行中运行Java字节码文件提示找不到或无法加载主类的问题

    测试类在命令行操作,编译通过,运行时,提示 错误: 找不到或无法加载主类 java类 package com.company.schoolExercise; public class test7_3_ ...

  7. 【java】查看Java字节码文件内容的方法+使用javap找不到类 解决方法

    研究synchronized底层实现,涉及到查看java字节码的需要 前提是,你的PC已经成功安装了JDK并别配置了环境变量. ==========查看方法========= 一.javap查看简约字 ...

  8. java字节码文件指令集

    网上找的没有指令码这列  自己把它加上 更方便查阅 指令从0x00-0xc9 没有0xba 常量入栈指令 指令码 操作码(助记符) 操作数 描述(栈指操作数栈) 0x01 aconst_null nu ...

  9. JAVA反射机制_获取字节码文件对象

    是在运行状态中,对于任意一个类 (class文件),都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性: 这种动态获取的信息以及动态调用对象的方法的功能称为java语 ...

随机推荐

  1. tcp/ip协议学习笔记一

    一. 简述 以前在学校学习计算机网络的时候学习多是网络7层模型OSI,了解了一些基本的计算机网络概念和协议通信格式,但是一直没弄明白其中的原理,包括各层之间的关系,应用,还有一些常见的令牌环网到底是什 ...

  2. centos 下yum 安装nginx

    centos 下yum 安装nginx 1. 直接yum install nginx不行,要先处理下源: rpm -ivh http://nginx.org/packages/centos/6/noa ...

  3. SciPy fftpack(傅里叶变换)

    章节 SciPy 介绍 SciPy 安装 SciPy 基础功能 SciPy 特殊函数 SciPy k均值聚类 SciPy 常量 SciPy fftpack(傅里叶变换) SciPy 积分 SciPy ...

  4. 8051单片机中访问int中字节的方法

    在使用单片机中,unsigned int 占2个字节,unsigned char 占一个字节.而单片机是实行的字节寻址.16字节的bit寻址实在是不好用, 不好用在不能建数组. 在实际的开发过程中,要 ...

  5. Program-Language

    1. 主流编程语言 2. 编程语言分类     2.1 编译or解释     2.2 按照客观系统的描述可分为两类     2.3 按照编程范型可分为 3. 语言范式 Paradigm 4. 计算机语 ...

  6. Java笔记--多线程

    1.线程的创建与运行(方式一): --1)创建一个Thread的子类: --2)重写Thread类的run()方法: --3)创建一个子类的对象: --4)调用线程的start()方法来启动线程,Ja ...

  7. java不要登录发送邮件noReply

    最近在工作中遇到一个问题: 客户需要让我们的系统给他们发邮件,但是不给我们提供用户密码. 这样就导致一个问题,即,一般我们使用的都是smtp方式发邮件,发邮件的时候必须登录,虽然可以修改发件人的邮箱名 ...

  8. 006.CI4框架CodeIgniter, 加载框架的helper辅助类,调用helper类中的各种函数

    01. CI4框架作为一个很成熟的框架,给我们提供了很多helper辅助类,我们在代码中可以很方便的使用,如下所示,我们在Controllers中调用Cookies类的set_cookie函数 < ...

  9. awk&sed

    sed BRE       awk  ERE sed 不能采用?   awk可以 sed 在匹配的任何时候可以用^,$ awk必须除了在行头和行尾 其他地方必须转义

  10. 已解决!kali桌面无法放置快捷方式问题

    kali不知从哪个版本更新之后桌面上就不能添加快捷方式了,经过一番折腾找到了解决方法. 1.终端运行命令:apt-get install gnome-shell-extension-desktop-i ...