美文网首页
try...catch...finally与return

try...catch...finally与return

作者: 叛逆的青春不回头 | 来源:发表于2019-03-14 19:12 被阅读0次

1.try...catch...finally块中的finally是否一定会执行?

  • try语句没有被执行到,如在try语句之前就返回了,这样finally语句就不会执行,这也说明了finally语句被执行的必要而非充分条件是:相应的try语句一定被执行到。
  • 在try块中有System.exit(0)这样的语句,System.exit(0);是终止Java虚拟机JVM的,连JVM都停止了,所有都结束了,当然finally语句也不会被执行到。

2.那finally在try-catch的return的之前还是之后执行?

(1)finally语句是在try的return语句执行之后,return返回之前执行。

public class MyClass {
    public static void main(String[] args) {
        System.out.println(testReturn());
    }
  public static String testReturn() {
      try {
          System.out.println("try block");
          return testStatement();
      } finally {
          System.out.println("finally block");
      }
  }
​
  public static String testStatement() {
      System.out.println("testStatement block");
      return "after return";
  }
}

运行结果为:

try block
testStatement block
finally block
after return

可以看到,try中的return语句先执行了,输出“testStatement”。但并没有立即返回,等到finally执行结束后,再进行返回输出“after return”。那当finally也有return的时候又是怎样的呢?

(2)finally如果有return语句,则会覆盖try(或catch)中的return语句;如果没有,对于原来的返回值,finally可以修引用所对应的对象,无法改变基本类型。

public class MyClass {
    public static void main(String[] args) {
       System.out.println("testObject: "+testObject());
     System.out.println("testPrimitive: x="+testPrimitive());
    }
    public static Student testObject() {
        Student result = new Student("Tom", 0);
        try {
            result.setAge(1);
            return result;
        } catch (Exception e) {
            result.setAge(2);
            return result;
        } finally {
            result.setAge(3);       //引用类型的返回值,可被修改
//            return new Student("Kobe", 33);   //可以被“具体值”覆盖
        }
    }
   public static int testPrimitive() {
        int x = 0;
        try {
            return x=1;
        } catch (Exception e) {
            x = 2;
            return x;
        } finally {
                x = 3;          //基本类型的返回值,不可被修改
//                return 3;    //可以被“具体值”覆盖
        }
    }
​
    private static class Student {
        private String name;
        private int age;
​
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
        @Override
        public String toString() {
            return "Student [name=" + name + ", age=" + age + "]";
        }
        public void setAge(int age) {
            this.age = age;
        }
    }
}

给出下finally中没有return的情况的结果:

testObject: Student [name=Tom, age=3]
testPrimitive: x=1

在finally没有return的情况下,对于基本类型x=1的值,finally中的x=3并没有起作用;而为引用时,finally中result.setAge(3)起作用了。

(3)异常发生时,try中的return语句不会被执行,catch中的return的执行情况与try中return的执行情况一样。

public class MyClass {
    public static void main(String[] args) {
        System.out.println("x = "+testCatch());
    }
    public static int testCatch() {
        int x = 20;
        try {
            System.out.println("try block");      
            x = x /0;
            return x += 80;
        } catch (Exception e) {
        System.out.println("catch block");
            return x += 15;
        } finally {
            System.out.println("finally block");
            if (x > 25) {
                System.out.println("x > 25, x = " + x);
            }
            x += 50;
        }
    }
}

运行结果:

try block
catch block
finally block
x>25, x = 35
x = 35

try中发生异常后,try中的return没有执行,而是先执行catch中的return,确定了返回值后再去执行finally块,执行完了catch再返回,finally里对x的改变对返回值无影响,原因同前面一样,也就是说情况与try中的return语句执行情况一样。

【====总结====】

执行时机问题。finally总会执行(除非是System.exit()),正常情况下在try后执行,抛异常时在catch后面执行。

返回值问题。 可以认为try(或catch)中的return语句的返回值放入线程栈的顶部:如果返回值是基本类型则顶部存放的就是值,如果返回值是引用类型,则顶部存放的是引用。 return的时候是复制了一个变量然后返回,所以之后finally操作的变量如果是基本类型的话不会改变其返回值, 但如果返回值是引用类型的话,因为指向同一个对象,就会改变其返回值。但不管是基本类型还是引用类型,都可以被finally返回的“具体值”具体值覆盖。

相关文章

  • try...catch...finally与return

    1.try...catch...finally块中的finally是否一定会执行? try语句没有被执行到,如在t...

  • 捕获异常

    try...catch...finally的执行逻辑 执行结果

  • return

    return 语句 下面的return 语句都会终止函数后面的执行: return false与 return t...

  • try...catch...finally

    try代码块的内容抛出错误后,会直接进入catch,执行catch代码块的内容 try代码块抛出错误(上例用的是t...

  • for、for...in...、forEach的区别

    for 与 for...in... 循环中return 会直接跳出循环,不进行下次循环forEach return...

  • 啊,似乎没有真正理解 try...catch...finally

    写了那么久的 JavaScript,似乎真的没有很认真地去了解 try...catch...finally 的各种...

  • java-try...catch...finally

    try...catch...finally由两段代码展开下面要讨论的话题 try..catch...finally...

  • continue与break与return

    1(循环)2(循环+switch)1(方法) continue 跳出本次循环继续下一次循环 break中止(小暴力...

  • 2020-07-08异常处理

    复制文件的异常处理 try...catch...finally的做法 JDK7改进方案——自动释放资源(close方法)

  • Java finally与return

    在try-catch-finally块中finally有两种情况不会执行 1.在try-catch块中调用syst...

网友评论

      本文标题:try...catch...finally与return

      本文链接:https://www.haomeiwen.com/subject/ajocmqtx.html