下面我们通过分析下当前方法的字节码,来说明为什么。 查看字节码命令:javap -verbose class文件 知识点简单概要: 看如下字节码需要简单了解下栈的结构。...下面字节码主要是对操作栈和局变量表的操作。...因为这个是实例方法,不是静态方法,他默认会传过来当前实例的引用,也就是this变量) 字节码执行路径 通过字节码我们发现在编译成class文件的时候,已经把三种执行路径都写到class文件中了。...第[18-19]行,finally块代码:i=3 第[20-22]行,执行catch块中return语句,把临时存储的 i 值返回。...,并抛出(无返回值) 结论 通过字节码,我们发现,在try语句的return块中,return 返回的变量并不是直接返回 i 值,而是在执行finally块之前把i值存储在临时区域,当执行return时直接返回的临时区域中的值
通过字节码理解try-catch-finally 场景 对于以下代码: public int test() { int x; try { x = 1; return x; } catch (Exception...其中,字节码行号0到7就是没有异常时的字节码流,返回值为1。 需要注意的是,上述Code中,第4、5行即为finally中的:x=3。...编译器自动在每段可能的分支路径之后都将finally语句块的内容冗余生成一遍来实现finally语义。同样的还有第13、14行,第19、20行。...从异常表中还可以发现另一问题,在catch块中如果出现了异常(第8到12行),那么也会跳到第17行进行处理,也就是执行finally代码块。...注:对于x=1;这条语句,虽然在字节码中体现为iconst和istore两条字节码,但是他们依然是原子操作,原子操作不是说只有一条指令,而是不可中断的一个或一系列操作。
本文主要介绍的关于异常处理的时候try-catch-finally块的执行顺序,一般情况下,finally块是会执行,在Java中,try-finally块的执行顺序通常遵循以下规则: try块中的代码首先被执行...如果try块中的代码执行完毕,控制流将转到finally块。无论try块中的代码是否抛出异常,finally块中的代码都将被执行。...finally块中的代码执行完毕后,整个try-finally块结束,控制流将继续到下一个语句或代码块。...finally块,try中的return结果会放在类似一个队列中,之后如果finally中有return语句,则会把finally中的return语句中的结果放入队列中,最终的是队列中的第一个数据,即finally...try块与finally块中都有return,所以最终返回结果就是finally中的return结果。 我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!
一、背景 对于很多初学者而言,会想当然地认为 “finally 代码块一定会被执行”,因此我们可以看下面这个案例: public class Demo { public static void...{ System.out.println("Exiting the program"); } } } 问题是:该段代码 finally 的代码块一定会被执行吗...二、分析 通常实际编码时,捕获异常后会记录日志或者将异常抛出等,此时 finally 代码块一般肯定会被执行到。 那么如何才能不执行finally呢?...finally 代码块呢?...因此如果我们可以修改 SecurityManager 如果检查退出时抛出异常,那么在 执行 System.exit(2) 时就会发生异常,最终依然会执行到 finally代码块。
1、前言 对于很多初学者而言,会想当然地认为 “finally 代码块一定会被执行”,因此我们可以看下面这个案例: public class Demo { public static void...{ System.out.println("Exiting the program"); } } } 问题是:该段代码 finally 的代码块一定会被执行吗...2、问题分析 通常实际编码时,捕获异常后会记录日志或者将异常抛出等,此时 finally 代码块一般肯定会被执行到。 那么如何才能不执行finally呢?...是否一定不会执行到 finally 代码块呢?...因此如果我们可以修改 SecurityManager 如果检查退出时抛出异常,那么在执行System.exit(2) 时就会发生异常,最终依然会执行到 finally代码块。
catch: 当异常发生时,会执行这个块中的代码,用于捕获和处理异常。finally: 不管是否发生异常,都会执行这个块中的代码,用于执行清理工作。...以下是一个示例:try: # 可能会引发异常的代码except SomeException as e: # 处理异常的代码,e 是捕获的异常对象4. finally 语句块finally 语句块用于包裹必须无论异常是否发生都要执行的代码...无论 try 块中的代码是否引发异常,finally 块中的代码都会执行。...# 无论是否发生异常,都会执行这里的代码在这种情况下,try 块中的代码正常执行,不会引发异常,因此 catch 块中的代码将被跳过,而 finally 块中的代码将始终执行。...最后,finally 块中的代码将始终执行。这种情况下,finally 块通常用于清理资源。5.3.
基于字节码的Java代码审计 之前看了基于字节码的Java代码审计工具的实现,最近终于有空可以好好看一下其是如何实现的了。本文并不会从代码出发,而是试图从字节码角度分析其可行性。...只要编译成为符合字节码规范的内容,均可以在Java虚拟机中运行。...至此字节码执行一个函数的过程就结束了,这里就可以进入下一个问题了 使用字节码进行审计 首先看这一段代码: public class RceYes{ public void eval(String...实现 上文已经找到了字节码代码审计的关键,那接下来如何通过代码去实现呢?首先第一个问题,如何将Class文件解析成字节码指令的形式。...这里就不得不提一下ASM了,作为字节码增强技术,它可以动态修改字节码或者是遍历类的结构,ASM此处就不进行深入展开了,我们单单看一下遍历类结构这一点,它会按照一定顺序逐语句对字节码进行解析,当解析到函数时我们就可以自定义一个局部变量表以及操作数栈来进行模拟操作
1.2字节码 字节码(Byte-code)是一种包含执行程序、由一序列 op 代码/数据对组成的二进制文件。字节码是程序的中间表示形式:介于人类可读的源码和机器码之间。...它经常被看作是包含一个执行程序的二进制文件,更像一个对象模型。字节码被这样叫是因为通常每个操作码 是一字节长,所以字节码的程度是根据一字节来的。...字节码也是由,一组操作码组成,而操作码实际上是对栈的操作,可以移走参数和地址空间,也可以放入结果。JAVA通过JIT(即时编译)可以将字节码转换为机器码。 字节码的实现方式是通过编译器和虚拟机器。...编译器将源码编译成字节码,特定平台上的虚拟机器将字节码转译为可以直接执行的指令。在java中一般是用Javac编译源文件变成字节码,也就是我们的class文件。...2.字节码执行 2.1JVM桢栈结构: 方法调用在JVM中转换成的是字节码执行,字节码指令执行的数据结构就是栈帧(stack frame)。也就是在虚拟机栈中的栈元素。
Jvm 如何确定方法的参数的个数 找到 Method 的 DescriptionIndex 的属性,找到对应的描述,例如: public class AddMain { public static...java 代码,add 方法对应的代码是 (II)I,最后一个 I 代表返回值,这个代表两个整型的参数...., int b,String c,boolean d) { return a + b; } 同样,(IILjava/lang/String;Z)I 代表有4个参数,字符串的表示是...(本文完) 作者:付威 博客地址:http://blog.laofu.online 如果觉得对您有帮助,可以下方的RSS订阅,谢谢合作 如有任何知识产权、版权问题或理论错误,...本文是付威的网络博客原创,自由转载-非商用-非衍生-保持署名,请遵循:创意共享3.0许可证 交流请加群113249828: 点击加群 或发我邮件 laofu_online
---- 正确的关闭资源方式 ---- 1、使用finally块来关闭资源,保证关闭操作总是会被执行; 2、关闭每个资源之前首先判断资源的引用变量不为null,避免NPE发生; 3、为每个资源使用单独的...try...catch 块关闭,保证关闭此资源发生异常,不会影响后面资源的关闭; 4、finally块不要使用return语句。...return语句直接导致方法结束,不会再跳回去执行try、catch块中的任何代码; 5、不要出现System.exit(0),会直接停止当前线程,finally块不会执行; 6、finally块中不要抛出异常...,如果抛出异常,finally块中的异常会覆盖try块抛出的异常,导致莫名奇怪的现象; 参见:Java陷阱之:finally块抛出异常或return导致异常丢失 Java陷阱之:finally块抛出异常或
阿牛今天提了个问题:volatile关键字的字节码实现是怎么样的?为什么我把volatile加上和去掉得到的字节码时一样的? ?...image.png 回答:内存屏障的概念是针对CPU架构级别的,需要在JIT编译器生成机器码的时候才能看到。
Java 诞生之初就曾宣扬过它的初衷,「一次编写,多处运行」,而它之所以能够实现跨平台的一个核心点就在于,Java 引入「字节码」屏蔽了与底层操作系统之间的差异。...同一段 Java 程序在编译后生成的字节码文件是唯一的,不会因为平台的不同而产生任何的变化。而同一段字节码跑在不同实现的 JVM 上,会产生不同的机器指令。...因此,你的同一段字节码在不同平台下的 JVM 上运行,会对应到不同的机器指令,以此实现了跨平台运行。...那么,本文就来分析一下这个「字节码」文件,解开它的神秘面纱。...话可能有点绕,但主要意思就是,JVM 拒绝运行比自己版本低的 Class 文件。 常量池 常量池算是类文件中比较繁琐的一块内容了,在解析它之前我们先看一段 Java 代码。
Javassist 前面文章介绍的 ASM 入门门槛还是挺高的,需要跟底层的字节码指令打交道,优点是小巧、性能好。...Javassist 是一个性能比 ASM 稍差但是使用起来简单很多的字节码操作库,不需要了解字节码指令,由东京工业大学的数学和计算机科学系的教授 Shigeru Chiba 开发....Javassist使用户不必关心字节码相关的规范也是可以编辑类文件的。...类文件编辑 Javassist可以在运行时修改类的字节码,从而实现一些功能,比如动态修改类的字段、方法等。...字节码分析 Javassist可以对字节码进行分析,提取类的结构信息,比如类名、字段、方法等。
刚开始想直接将需要的class文件进行修改,发现这样一个问题,使用工具类将需要的位置字节码参数修改完之后,将修改后的文件压缩回原来的JAR,JAR不能用了。...IDEA插件:jclasslib Bytecode viewer jclasslib bytecode viewer 是一个可以可视化已编译Java类文件和所包含的字节码的工具。...另外,它还提供一个库,可以让开发人员读写Java类文件和字节码。...修改class文件 使用工具类修改class文件的的某个参数,或者某个字符串。这里有一点其实在java文件中定义的各种参数,编译成字节码文件的时候,都变成了字符串,只是逻辑位置不同,处于不同的域中。...然后就可以在IDEA中找到对应的域,如上图中,如果在方法中就点击Methods,从上到下分别是JAVA文件由上到下的定义顺序,找到对应的方法,就能看到下图中字节码详情: 如上图找到我们需要修改的字符串
,int j) { int f; if (i == j) { f = i + j; }else { f = i - j; } } 编译后的字节码...,并相减后将结果入栈 15: istore_3 //将相减的结果从栈顶弹出并赋值给局部变量表的第三个整型变量f 16: return.../跳转到EXIT标记处 ELSE: sub $r5,$r3,$r4 //如果不相等,则将r3寄存器和r4寄存器相减将结果放入r5寄存器 EXIT: 通过比较,其实也能看出来,Java字节码的入栈操作其实也就是放入寄存器中...public void print() { int sum = 0; for (int i = 0;i < 100;i++) { sum += i; } } 编译后的字节码...S5寄存器的值,如果如果结果为假跳转到EXIT标记i < 100 add $s3,$s4,$s3 //将s4寄存器和s3寄存器的值相加存入s3寄存器sum += i; addi $s4
你可能还见过另一种类型的文件是 .pyc 结尾的,它们就是 Python “字节码”文件。这里转载一篇文章,专门讲解 Python 字节码的相关内容,给大家看看。...大多数 Python 字节码指令操作的是当前调用栈帧的计算栈,虽然,还有一些指令可以做其它的事情(比如跳转到指定指令,或者操作块栈)。...dis 模块的使用 dis 模块包括一些用于处理 Python 字节码的函数,可以将字节码“反汇编”为更便于人阅读的形式。查看解释器运行的字节码还有助于优化代码。...第二列(可选)指示当前执行的指令(例如,当字节码来自帧对象时)【这个例子没有】 第三列 一个标签,表示从之前的指令到此可能的 JUMP 【这个例子没有】 第四列 数字是字节码中对应于字节索引的地址(这些是...其中 SETUP_FINALLY 字节码的含义是将 try 块从 try-except 子句推入块堆栈。 这里可以看出将 LOAD_NAME 将 j 压入栈之后就报错了。
2.java字节码 java bytecode 是由单字节(byte)的指令组成,理论上最多支持256个操作码(opcode)。...实际上java只使用了200左右的操作码,还有一些操作码保留给调试使用。 java字节码的分类: 1.栈操作指令,包括与局部变量交互的指令。 2.程序流程控制指令。...2.1 如何生成字节码如何生成字节码?...后续4位为0x000005,表示后续指令将占5个字节,为0x2AB70001B1,这部分内容为虚拟机运行的字节码指令,可以参考虚拟机字节码指令表进行对照。...这就是第二个方法的字节码。
在前文中已经介绍了JVM的premain和attach功能, 本文介绍下JBOSS开源的代码注入工具: byteman....与之前讲的premain和attach不同, byteman是通过规则文件完成代码注入等功能. 一....AT ENTRY //目标方法的第一个指令之前 AT EXIT //目标方法的所有正常返回点 AT LINE number //目标方法行号 AT READ [type .] field [count...方法返回值 $@ 方法参数, 与$1 $2相同 $^ 方法异常时, 异常信息 三. byteman的attach模式与helper byteman除了上述的agent方式外, 还有attach模式, 能够在服务正常运行的情况下...IDE中开发 为了方便运行, 每次在命令行中执行是非常低效的. 所以, 在IDE中能开发运行是非常必要的.
java之JVM的字节码结构 1、魔数 所有.class文件的前四个字节都是魔数,魔数的固定值为0xCAFEBABE。...2、版本号 版本号为魔数后的4个字节,前2个字节显示下一个版本号,后2个字节显示主版本号。 主版本号后的字节是常量池入口。在常量池中保存两种常量:字面量和符号引用。...这两个字节保存的值为常量池中的索引值,根据索引值就能在常量池中找到这个类的全限定名。 6、父类名称 当前类名后的两个字节,描述父类的全限定名,同上,保存的也是常量池中的索引值。...7、接口信息 父类名称后为两字节的接口计数器,描述了该类或父类实现的接口数量。紧接着的n个字节是所有接口名称的字符串常量的索引值。...8、字段表 字段表用于描述类和接口中声明的变量,包含类级别的变量以及实例变量,但是不包含方法内部声明的局部变量。 以上就是java之JVM字节码结构的介绍,希望对大家有所帮助。
Kotlin是一门JVM语言,它被google大力推广,现如今已经是Android官方推荐的开发语言了。为了更好的学习Kotlin,你必须要从字节码的角度来看待语法特点,这样可以更好的加深自己的理解。...这篇文章就是教大家如何通过Android studio来查看Kotlin编译后的字节码。...1、首先选中你要显示字节码的文件,之后点击顶部工具栏中的 Tools – 选中 Kotlin – 在弹出菜单中点击 Show Kotlin Bytecode。 ?...2、点击之后在Android studio最右侧的工具栏上会有一个增加一个 Kotlin Bytecode 按钮,点击之后会显式详细的Kotlin文件的字节码。 ?...3、在新的窗口中详细的列出了字节码信息,但是阅读字节码信息需要有相关的知识储备,为了方便阅读,这个时候可以点击新窗口中的 Decompile 按钮,把字节码转换成更易懂的语句结构。 ?
领取专属 10元无门槛券
手把手带您无忧上云