java-一个值得深思的问题。

问题描述

一个值得深思的问题。
 public class FinallyTest {
    public int test() {
        int i = 0;
        try {
            i++;
            return i;
        } finally {
            i--;
        }
    }
    public static void main(String[] args) {
        System.out.println(new FinallyTest().test());
        ;
    }
}

碰到一个问题:
自己分析: finally块应该是在return之前执行吧。
Debug调试发现,当执行到return i;时,下一步执行 finally块。
然后 到 return i;这行。i的值虽然i--了,但还是没执行finally块前的值。。
表述可能不清,可运行下看看。
我有点不明白其中的执行过程。

解决方案

是这样的,函数的返回值是return i;决定的。注意,这里return i;其实是对i求值之后记录下返回值,在函数返回的时候返回。
固然i--;会改变i,但是返回值此时已经确定了。

    public int test() {
        int i = 0;
        try {
            i++;
            return i;
        } finally {
            i--;
            return i;
        }
    }

这样写返回0,因为返回值被再次刷新了。
你可以把return il看成如下代码
[result] = i;
[result]是一个编译器产生的隐含变量
你的程序其实是

 public int test() {
        int i = 0;
        try {
            i++;
            [result] = i;
        } finally {
            i--;
        }
    }

解决方案二:

这需要从虚拟机角度考虑,编译器使用异常表而不是简单的跳转命令来实现Java异常及finally处理机制。简单的说就是,编译后的字节码,会将return语句的返回值保存到栈,然后再执行finally,由于return的值在finally之前已经保存在栈中,所以不管finally怎么更改,都不会改变return的值

解决方案三:

@ caozhy
caozhy 讲的不错

解决方案四:

caozhy 说的是对的,返回的值已经确定了

解决方案五:

这个属于java语言的天生的缺陷,不要深思,更不要卖弄。

eclipse中建议直接在:项目/属性/java编译/警告错误中


finally block does not complete normally

设置为error!

解决方案六:

一个值得程序员深思的问题
值得深思的问题
值得深思的問題

时间: 2024-09-21 21:44:20

java-一个值得深思的问题。的相关文章

10个值得深思的 PHP 面试问题

10个值得深思的 PHP 面试问题 文章所罗列的问题虽然看似简单,但是每个背后都涵盖了一个或几个大家容易忽视的基础知识点,希望能够帮助到你的面试和平时工作. Q1 第一个问题关于弱类型 $str1 = 'yabadabadoo'; $str2 = 'yaba'; if (strpos($str1,$str2)) { echo "\"" . $str1 . "\" contains \"" . $str2 . "\"&

10个值得深思的PHP面试题_php技巧

文章所罗列的问题虽然看似简单,但是每个背后都涵盖了一个或几个大家容易忽视的基础知识点,希望能够帮助到你的面试和平时工作. Q1 第一个问题关于弱类型 $str1 = 'yabadabadoo'; $str2 = 'yaba'; if (strpos($str1,$str2)) { echo "/"" . $str1 . "/" contains /"" . $str2 . "/""; } else { ec

值得深思的网络爆料

本报记者 陈玺撼 孟群舒 实习生 张莉莉 近期,围绕网络爆料"安信地板甲醛超标"的事件,引发社会强烈关注.截至目前,各地质监部门和万科出具的180份检测报告中,佛山某楼盘出现一例不合格情况,其余179份报告均未发现甲醛超标现象.在事件基本告一段落之际,回顾这一事件,仍有不少值得深思的地方. 全国送检仍有一例甲醛超标 安信地板事件始于2月16日一个网络爆料,名为"李晓燕"的网友称:安信地板自2008年起与万科集团等多家知名房地产企业合作以来,提供大量有毒.劣质地板,有

java方法-java一个方法形参有两个,如何在调用的时候只传入一个参数

问题描述 java一个方法形参有两个,如何在调用的时候只传入一个参数 如题,有一个方法里两个形参,我另一个文件类中一个方法想要那个方法的返回值,可是第二个参数在这里用不到,能否只传第一个参数 如何实现,前提这个类不能继承后重写方法,因为多人合同写的. 解决方案 不可以,变通的办法是再写一个只有一个参数的函数重载形式,在其中给另一个参数一个预设值,间接调用. 解决方案二: 一个Action调用两个不同的方法 解决方案三: 调用的时候给一个无影响的值 解决方案四: 讲道理的话是不能这样做的,不过如果

关于java一个计算和图像打印的像素强度值的直方图的问题

问题描述 关于java一个计算和图像打印的像素强度值的直方图的问题 问题在这个网址上,希望大家能帮我解答一下,不胜感激!http://www.cs.unc.edu/~kmp/comp401sp16/assignments/a2/sp16-a2.html 解决方案 建议你自己将问题翻译为中文,否则后果可想而知.

java一个已继承东西的类如何使用actionSupport里的getText()方法

问题描述 java一个已继承东西的类如何使用actionSupport里的getText()方法 java中,我的一个公共类已继承了一个java类,如何在这个类里使用actionSupport里的getText()方法? 解决方案 ActionSupport.getText()方法ActionSupport.getText()方法ActionSupport.getText()方法 . 解决方案二: 呵呵 经验告诉我 有办法 单继承的java 一般会有俩种机制 1:是继承 2:是实现接口,

java一个类不能实现同一泛型接口的两种变体

问题描述 java一个类不能实现同一泛型接口的两种变体 今天看<JAVA编程思想>,看到泛型的时候看到**"一个类不能实现同一泛型接口的两种变体"**(P401) 这样一句话,请问为什么 例子一 例子二 例子三(正确) 解决方案 和java实现泛型的方式有关,java采用的是编译期的直接替换.这意味着可能出现相同的方法有两个参数一样的重载,这是不合法的.

如何查看java一个类的大小

问题描述 如何查看java一个类的大小 就比如我搞了一个类,然后往里边set各种值,我现在想知道这个类的占空间的大小?比如多少KB或者多少MB什么的? 解决方案 如果你知道你的类的路径的话,例如D:aa.txt 那么就 public static void main(String[] args) { FileInputStream fis = null; try { fis = new FileInputStream(new File("D:\aa.txt")); } catch (F

java一个mina框架的传输对象的问题

问题描述 java一个mina框架的传输对象的问题 我用mina传递一个对象,这个对象里面包含了一张图片的字节数组,和字节数组的长度,当我从客户端将该对象传到服务器的时候,每次只有发送1k的数据,速度很慢,但是从服务器向客户端发送时,发送速度会快很多,我在客服端和服务器端都设置了最大最小的读取缓存,求大神解答这是为什么?` 解决方案 mina单独没有用过 但是用过它和xmpp协议传输数据 传输的是string串 你可以试试 将这些字节转成string试试看 解决方案二: 不贴下主要函数的代码?