zoukankan      html  css  js  c++  java
  • java try finally返回值问题

    需要知道的是:finally的语句会先于try或者catch的返回语句之前执行,如果finally中有return语句,那么try或catch中的return语句会被finally中的return覆盖,不建议在finally中放return

    情况一:try、catch和finally中都有return

      public static void main(String[] args) {
            System.out.println(testInt());
        }
     private static int testInt(){
            int a = 0;
            try{
                return a;
            }catch (Exception e){
                a = 9;
                e.printStackTrace();
                return a;
            }finally {
                a = 10;
                return a;
            }
        }
    

    最后输出:
    10

    在try中的return执行之前,会执行finally中的语句,finally中有return,于是会覆盖掉try中的return。如果此时发生了异常,catch中的return语句会执行吗?看下面:

      public static void main(String[] args) {
            System.out.println(testInt());
        }
     private static int testInt(){
            int a = 0;
            try{
               int b = 7/a; //产生了异常
                return a;
            }catch (Exception e){
                a = 9;
                e.printStackTrace();
                return a;
            }finally {
                a = 10;
                return a;
            }
        }
    

    输出结果:
    10
    java.lang.ArithmeticException: / by zero
    at pattern.App.testInt(App.java:40)
    at pattern.App.main(App.java:31)
    产生了异常,catch中语句被执行,但是catch中的return执行之前会执行finally中的语句,所以catch中的return依然被覆盖

    情况二:try或者catch中有return,finally中没有return

    public static void main(String[] args) {
            System.out.println(testInt());
        }
    private static int testInt(){
            int a = 0;
            try{
                return a;
            }catch (Exception e){
                a = 9;
                e.printStackTrace();
                return a;
            }finally {
               System.out.println("执行finally");
                a = 10;
            }
    
        }
    

    输出:
    执行finally
    0
    可以看到,finally中的语句依然执行了,但是a的值在finally中改变了,返回值并没有改变,如果这里产生了异常呢?自然是会输出9的(可以自己验证一下),这里可以看到对于基本类型a,finally的赋值并没有改变返回值,如果是下面非基本类型的情况呢?

    情况三:对于非基本类型

     public static void main(String[] args) {
            System.out.println(testNum().getNum());
        }
     private static Num testNum(){
            Num num = new Num();
            int a = 0;
            try{
                num.setNum(7);
                return num;
            }catch (Exception e){
                e.printStackTrace();
                num.setNum(9);
    
            }finally {
                num.setNum(10);
            }
            return num;
        }
    

    最后输出结果:
    10

    同理如果是产生了异常,结果仍然是10(可以自己验证)
    可以看到,对于非基本类型,finally中的赋值最后在return中会被返回,通过看向志明《深入理解Java虚拟机》第187页讲解“class文件的属性表”的时候,找到了为什么:

      • 不管什么情况,finally中的语句总会执行(除非程序执行System.exit()),正常情况下载try后面执行,抛异常时载catch后面执行
      • 对于返回值问题。try(或者catch)中的return语句的返回值放入线程栈的顶部:如果返回值是基本类型则顶部存放的就是值,如果返回值是引用类型,则顶部存放的就是地址。finally中的return语句可以修改引用所对应的对象,无法修改基本类型。所以情况二中的基本类型finally无法修改,但是情况三可以修改
      • 不建议在finally中使用return
  • 相关阅读:
    TCP拥塞控制机制
    C/S 与 B/S 区别
    ext4文件系统新特性
    关于TCP慢启动和拥塞避免的题
    [信息图表]移动学习 Go Study
    [时间线]Android市场的发展
    学习,只有勤奋是不够的……
    UNIX域套接字实例
    程序员的本质
    淘宝Web服务器Tengine正式开源
  • 原文地址:https://www.cnblogs.com/Chary/p/12845842.html
Copyright © 2011-2022 走看看