最近学习的JVM小册中老师提了个问题:

  最开始我觉得是1,结果程序跑出来是0,感到很疑惑,于是查看了下字节码:

  

  从字节码可以看出:

  0:定义变量0

  1:将0存入本地变量表slot-0

  2:加载slot-0到操作数栈

  3:将栈顶元素存入本地变量表slot-1

  4:对slot-0自增

  7-8:加载slot-1到操作数栈并返回

  可以看到,最终返回的是slot-1的值,而自增的是slot-0的值,所以最终还是返回的0

  但是为什么JVM要这么做的原因的还是不太清楚,看了Java虚拟机规范上面写的:

  https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.10.2.5

  规范这里也说的是如果try里面有return,那么编译的时候会先把try的返回值存入到本地变量表中。看到这里我有了一些猜测:

  try-finally的原理是编译的时候在return之前插入了jsr指令,执行该指令会跳到finally block,finally block这个时候被编译成了一个subroutine(子程序),

也就是一个方法,那么为了当从subroutine跳转出来的时候能够继续返回原来要返回的值,所以在执行finally block之前会先把try的返回值存入本地变量表中一个新的slot,而在finally

当中如果有操作try的返回值这个变量的时候,实际操作的是该值原本所在的slot,,说的有点绕,不太好理解,望见谅。

  老师在群里发了个javac编译的代码,这个比较清楚:

  所以大致可以总结为:当try有return的时候,finally里面对try的返回值的操作不起作用。我们也可以将程序改一下:

  当try里面没有return的时候,则返回1。在看看此时的字节码:

  这个时候,就没有将return的值暂存的操作了。

try-finally的时候try里面带return的更多相关文章

  1. 装饰器1、无参数的装饰器 2、有参数的装饰器 3、装饰器本身带参数的以及如果函数带return结果的情况

     装饰器分成三种: 1.无参数的: 2.有参数的: 3.装饰器本身带参数的. 装饰器decorator又叫语法糖 定义:本质是函数,器就是函数的意思.装饰其他函数.就是为其他函数添加附加功能. 原则: ...

  2. 理清Java中try-catch-finally带return的执行顺序

    前言:try-catch-finally带return和异常时,它们之间执行顺序问题是留下来的一个小疑问,今天搞清楚它们 第一种情况:无异常 //1.try-catch-finally都带有retur ...

  3. python学习,day3:函数式编程,带return

    return的主要作用就是,在调用的时候,能知道函数的运行情况,相当于打个标签 # coding=utf-8 # Author: RyAn Bi def test1(): print('in the ...

  4. JAVA中try、catch、finally带return的执行顺序总结

    异常处理中,try.catch.finally的执行顺序,大家都知道是按顺序执行的.即,如果try中没有异常,则顺序为try→finally,如果try中有异常,则顺序为try→catch→final ...

  5. java return

    return语句的作用: 1.返回一个值,可以是任意类型的 2.使程序返回到操作系统,或者说是代表"已经做完,离开此方法" ---------------------------- ...

  6. SQL Server存储过程Return、output参数及使用技巧

    SQL Server目前正日益成为WindowNT操作系统上面最为重要的一种数据库管理系统,随着 SQL Server2000的推出,微软的这种数据库服务系统真正地实现了在WindowsNT/2000 ...

  7. 我敢说你不一定完全理解try 块,catch块,finally 块中return的执行顺序

    大家好,今天我们来讲一个笔试和面试偶尔都会问到的问题,并且在工作中不知道原理,也会造成滥用. 大家可能都知道,try 块用来捕获异常,catch块是处理try块捕获的异常,finally 块是用来关闭 ...

  8. java递归算法提前返回值带出

    /** * */ package testJava.java.foreach; import java.util.ArrayList; import java.util.LinkedList; imp ...

  9. return语句的用法

    1.return语句的作用:a.返回一个值,这个值可以是任意类型.b.使程序返回到操作系统(即终止程序)2.java中对于一个函数,不论有没有返回值类型,都可以带有return 语句.但是区别在于,r ...

随机推荐

  1. UNITY3D UGUI学习--canvas

    首先从canvas的参数说起走. Canvas Component是UI布局和渲染的抽象空间,所有的UI元素都必须在此组件之下. Render Mode UI的渲染方式,有三种: Screen Spa ...

  2. 【HttpRunner v3.x】笔记—8.运行testcase的几种方式

    在之前的demo过程中,已经运行过testcase了,那这篇就也来汇总一下,运行case相关的知识点. 一.运行testcase的几种场景 1. 运行单个case 通常单个case的话我会在编辑器里用 ...

  3. 飞跃原野(三维bfs)

    Problem Description 勇敢的法里奥出色的完成了任务之后,正在迅速地向自己的基地撤退.但由于后面有着一大群追兵,所以法里奥要尽快地返回基地,否则就会被敌人逮住. 终于,法里奥来到了最后 ...

  4. 转载:记录一次MySQL两千万数据的大表优化解决过程

    地址:https://database.51cto.com/art/201902/592522.htm 虽然是广告文,但整体可读性尚可.

  5. 哦!这该死的 C 语言

    前言 C 语言是一门抽象的.面向过程的语言,C 语言广泛应用于底层开发,C 语言在计算机体系中占据着不可替代的作用,可以说 C 语言是编程的基础,也就是说,不管你学习任何语言,都应该把 C 语言放在首 ...

  6. 用C、python手写redis客户端,兼容redis集群 (-MOVED和-ASK),快速搭建redis集群

    想没想过,自己写一个redis客户端,是不是很难呢? 其实,并不是特别难. 首先,要知道redis服务端用的通信协议,建议直接去官网看,博客啥的其实也是从官网摘抄的,或者从其他博客抄的(忽略). 协议 ...

  7. Ubuntu 安装配置 WordPress5.4.2

    一.安装 Apache 并配置 WordPress sudo apt-get install apache2 -y //  安装 apache2 sudo apt-get install php -y ...

  8. oracle之复杂查询(下):子查询

    复杂查询(下):子查询 8. 1 非关联子查询:返回的值可以被外部查询使用.子查询可以独立执行的(且仅执行一次). 8.1.1 单行单列子查询,子查询仅返回一个值,也称为标量子查询,采用单行比较运算符 ...

  9. Kubernetes调度流程与安全(七)

    一.Kubernetes中的调度流程 1,介绍 Scheduler 是 k8s 中的调度器,主要的任务是把定义的 Pod 分配到集群的节点上.Scheduler 是作为一个单独的程序运行的,启动之后会 ...

  10. openstack (共享组件) 时间同步服务

    云计算openstack共享组件——时间同步服务ntp(2)   一.标准时间讲解 地球分为东西十二个区域,共计 24 个时区 格林威治作为全球标准时间即 (GMT 时间 ),东时区以格林威治时区进行 ...