1.try-catch-finally return 执行顺序

如try中没有异常,则顺序为try→finally;
如try中有异常,则顺序为try→catch→finally;

2.try-catch-finally return 执行顺序

当try、catch、finally中加入return之后,就会有几种不同的情况出现:

A、try中带return---》执行顺序为try→finally;return的是try中的值

先执行try并保存try中return的值,等finally执行完后,返回保存的return值

private static int tryCF(){
        int a = 1;
        try {
            a++;
            System.out.println("try:" + a);
            return a;
        } catch (Exception e) {
            a++;
            System.out.println("catch:" + a);
        } finally {
            a++;
            System.out.println("finally:" + a);
        }
        return a;
    }

//----------------结果-------------------
try:2
finally:3
方法的返回值:2

B、try中带return,finally中也带return---》执行顺序为try→finally;try中的return会失效,返回的是finally中的值,编译是可以编译通过的,但是编译器会给予警告,所以不推荐在finally中写return这会破坏程序的完整性,而且一旦finally里出现异常,会导致catch中的异常被覆盖

//不推荐在finally中写return
private static int tryCF(){
        int a = 1;
        try {
            a++;
            System.out.println("try:" + a);
            return a;
        } catch (Exception e) {
            a++;
            System.out.println("catch:" + a);
        } finally {
            a++;
            System.out.println("finally:" + a);
            return a;
        }
        
    }

//----------------结果-------------------
try:2
finally:3
方法的返回值:3

C、catch中带return---》执行顺序为try→catch→finally;return的catch中的值。

catch中return与try中一样,会先执行return前的代码,然后暂时保存需要return的值,再执行finally中的代码,最后再通过return返回之前保存的值。所以,这里方法返回的值是try、catch中累积计算后的3,而非finally中计算后的4。

private static int tryCF(){
        int a = 1;
        try {
            a++;
            System.out.println("try:" + a);
            int x = a / 0 ;  
        } catch (Exception e) {
            a++;
            System.out.println("catch:" + a);
            return a;
        } finally {
            a++;
            System.out.println("finally:" + a);
        }
        return a;
        
    }

//----------------结果-------------------
try:2
catch:3
finally:4
方法的返回值:3

D、try-catch-finally中都带return,//不推荐在finally中写return

结果和B一样,finally会覆盖了try or catch的保存的return值

// 不建议在finally中return
// 不建议在finally中return
private static int tryCF(){
        int a = 1;
        try {
            a++;
            System.out.println("try:" + a);
            return a;  
        } catch (Exception e) {
            a++;
            System.out.println("catch:" + a);
            return a;
        } finally {
            a++;
            System.out.println("finally:" + a);
            return a;
        }
       
        
    }

//----------------结果-------------------
try:2
finally:3
方法的返回值:3

private static int tryCF(){
        int a = 1;
        try {
            a++;
            System.out.println("try:" + a);
            int x = a / 0;
            return a;  
        } catch (Exception e) {
            a++;
            System.out.println("catch:" + a);
            return a;
        } finally {
            a++;
            System.out.println("finally:" + a);
            return a;
        }
       
        
    }

//----------------结果-------------------
try:2
catch:3
finally:4
方法的返回值:4

3、finally中一旦发生异常,会把try,catch中的异常信息消化掉,程序中出现finally的报错,影响了try,catch的执行效果。

private static int tryCF(){
        int a = 1;
        try {
            a++;
            System.out.println("try:" + a);
            return a;  
        } catch (Exception e) {
            a++;
            System.out.println("catch:" + a);
            return a;
        } finally {
            a++;
            System.out.println("finally:" + a);
            int x = a / 0;
        }
       
    }

//--------------------------------
try:2
finally:3
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at TryCatchFinally.tryCF4(TryCatchFinally.java:33)
	at TryCatchFinally.main(TryCatchFinally.java:16)

4、开发中常出现的问题:不推荐的写法

 A、多个资源释放时,每个释放语句都要使用try保护,且不要将多个资源释放语句写在同一个try块内

// 多个资源释放时,每个释放语句都要使用try保护,且不要将多个资源释放语句写在同一个try块内
private static void testObj(String filePath){
        File file = new File(filePath);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(oos);
            oos.close();//多个资源释放
            fos.close();//多个资源释放
        } catch(FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
}

//----------推荐写法--------

//Java7及以上版本可以使用try-with-resources语句自动释放资源
//语法糖:简单易读
    private static void testObjGood(String filePath){
        File file = new File(filePath);
        try (FileOutputStream fos = new FileOutputStream(file);
             ObjectOutputStream oos = new ObjectOutputStream(fos))
        {
            oos.writeObject(oos);
        } catch(FileNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

B、问题一:finally中多个资源的释放,不能放在同一个try块内;

问题一:finally中的fos,oos有空指针的风险

private static void testObj2(String filePath) {
        File file = new File(filePath);
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        try {
            fos = new FileOutputStream(file);
            oos = new ObjectOutputStream(fos);
            oos.writeObject(oos);
        } catch(FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                oos.close();//多个资源的释放
                fos.close();//多个资源的释放
            } catch (IOException e){
                e.printStackTrace();
            }
        }
    }
//----------------推荐写法第二-------------------
//Java7及以上版本可以使用try-with-resources语句自动释放资源
//语法糖:简单易读
private static void testObjGood22(String filePath) {
        File file = new File(filePath);
        try (FileOutputStream fos = new FileOutputStream(file);
             ObjectOutputStream oos = new ObjectOutputStream(fos))
        {
            oos.writeObject(oos);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } 
    }

//----------------推荐写法第一-------------------

private static void testObjGood2(String filePath) {
        File file = new File(filePath);
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        try {
            fos = new FileOutputStream(file);
            oos = new ObjectOutputStream(fos);
            oos.writeObject(oos);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (oos != null) {
                try {
                    oos.close();//多个资源的释放
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();//多个资源的释放
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
04-27 18:46