Java try catch finally return 说明

本渣今天帮师兄做笔试,读Java程序 发现答案跟我想的完全不一样,最后一查才发现自己想的完全是错的
,赶紧记录一下,希望能帮到需要的人。

在实际开发中,根据 try catch 语句的执行过程,try 语句块和 catch 语句块有可能不被完全执行,而有些处理代码则要求必须执行,例如文件的关闭、释放资源等,此时就可以将这些代码放在 finally 语句块中。

finally 语句可以与前面介绍的 try catch 语句块匹配使用,语法格式如下:

try{
    逻辑代码块
}catch(ExceptionType e){
    异常处理代码块
}finally{
    清理代码块
    文件关闭
    释放资源
}

try catch finally 语句执行流程图
图一 try catch finally 语句执行流程图

try catch finally 语句块的执行情况可以细分为以下 5 种情况:

  1. 如果 try 代码块中没有拋出异常,则执行完 try 代码块之后直接执行 finally 代码块,然后执行 try catch finally 语句块之后的语句。
  2. 如果 try 代码块中拋出异常,并被 catch 子句捕捉,那么在拋出异常的地方终止 try 代码块的执行,转而执行相匹配的 catch 代码块,之后执行 finally 代码块。如果 finally 代码块中没有拋出异常,则继续执行 try catch finally 语句块之后的语句;如果 finally 代码块中拋出异常,则把该异常传递给该方法的调用者。
  3. 如果 try 代码块中拋出的异常没有被任何 catch 子句捕捉到,那么将直接执行 finally 代码块中的语句,并把该异常传递给该方法的调用者。
  4. 在前面的代码中用 System.exit() 退出运行。如果代码在 try 内部执行一条 System.exit() 语句,则应用程序将终止而不会执行 finally。
  5. 如果在执行 finally 块之前,程序所在的线程死亡,finally 块将不被执行。

实例1:
我知道 return a++; 是先 return 再+1的,但是如果用try/finally语句捕获时,突然发现有三种有趣的情况:

 1. return a++;
 2. return ++a;
 3. return a+1;

分别在finally语句会有不同的输出。

public class test {
    public static void main(String[] args) {
        System.out.println("s:"+test(1));
    }
    static int test(int a){
        try {
            //依次修改此处
            return a++;
            //return ++a;
            //return a+1;
        }finally {
            System.out.println("f:"+a);
        }
    }
}

  1. return a++;
f:2
s:1
  1. return ++a;
f:2
s:2
  1. return a+1;
f:1
s:2

我们知道finally语句是在方法结束前运行的,

原因:程序中try内部没有异常的情况下,若有finally,且finally中没有return。若在try中遇到return,则先跳去执行finally中的代码,在回来执行try中return。

其实上述代码反编译字节码之后会发现:

原来其实return后面的表达式,编译器会创建临时变量,操作完成再返回

import java.io.PrintStream;

public class Test
{

    public Test()
    {
    }

    public static void main(String args[])
    {
        System.out.println((new StringBuilder()).append("s:").append(test(1)).toString());
    }

    static int test(int a)
    {
        int i = a++;//主要改此处
        System.out.println((new StringBuilder()).append("f:").append(a).toString());
        return i;
        Exception exception;
        exception;
        System.out.println((new StringBuilder()).append("f:").append(a).toString());
        throw exception;
    }
}

实例2:

public class TryTest {
 
	public static void main(String[] args) {
		String result = get();
		System.out.println(result);
	}
	
	public static String get(){
		int value = 0;
		try {
			System.out.println("try……");
			//等式1/0 :分母为0 的明显错误          ——制造错误(用于抛异常)
			int result = 1 / value;
			return "111";
		} catch (Exception e) {
			System.out.println("catch……");
			return "444";
		} finally {
			System.out.println("finally……");
			return "333";
		}
		
//		return "222";
	}

结果:
在这里插入图片描述

经过测试:

  1. 在通过编译器的检查后,如果finally中有return,则以finally中的return为准,其他的都将失效,return之前的代码都有效。
  2. 第37行的return “222” 于catch、finally中的任何一个return互斥。也就是说,在catch、finally中其中一个地方存在return,编译器就能检查,已符合方法的返回要求。
  3. catch和finally中,可同时存在return,编译能通过。但程序以finally中的return “333”为准,不会理睬catch中的return “444”,catch中return之前的代码仍然生效。

实例3:以下程序不会执行 try……Catch……finally之外的return,即打印的是“111”,而不打印“222”

public static void main(String[] args) {
        // 调用 测试方法
        String result = get();
        // 打印 测试方法返回的结果
        System.out.println(result);
    }

    public static String get(){
        try {
            System.out.println("try……");

            return "111";

        } catch (Exception e) {
            System.out.println("catch……");
        } finally {
            System.out.println("finally……");
        }

        return "222";
   }

结果:
在这里插入图片描述

参考文献1:try、catch、finally中return的执行顺序
参考文献2:finally语句与return a++

发布了34 篇原创文章 · 获赞 21 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/lizhengze1117/article/details/101639446