每一秒钟的时间都值得铭记

0%

Java异常try{}catch{}中的return机制

什么是Java的异常体系?参考博客:Java基础——运行时异常和非运行时异常

Java异常的处理方式

throw

  • throw是Java中的一个关键字,可以在方法上声明抛出一个异常,如果方法体中发生了异常,那么方法会通过throw关键字将异常抛出。
  • Java使用throw关键字抛出异常后,会抛给调用该方法的上一层方法,如果该异常是非运行时异常,那么调用该方法的上一层方法,也需要进行异常处理,throw或者try{}catch{}
  • 如果该方法声明抛出后,方法中发生了异常,而且该方法是最顶层的方法,没有其他方法调用该方法,那么异常就会被抛给JVM,由JVM进行异常处理。

try{}catch{}

  • 在Java的异常体系之中,除了使用throw关键字将异常声明抛出之外,还可以使用try{}catch{}的方式将异常捕获。
  • Java的异常中,非运行时异常,Java代码编译规定必须进行显式处理的,要么使用throw进行抛出,要么就使用try{}catch{}进行异常的捕获。

try{}catch{}的执行顺序

正常情况

  • 如果是正常情况,代码中没有异常发生,那么代码只会执行try{}中的代码,而catch{}中的代码不会执行。
    1
    2
    3
    4
    5
    try {
    System.out.println("代码正常执行......");
    } catch (Exception e) {
    System.out.println("代码发生异常后执行......");
    }
    正常情况下,以上代码的执行结果是:
    1
    代码正常执行......

发生异常

  • 如果try{}中的代码发生了异常,那么发生异常前的代码会正常执行,而try{}中发生异常后的代码将不会再执行(除了return之外),而是执行catch{}中的代码。
    1
    2
    3
    4
    5
    6
    7
    try {
    System.out.println("代码正常执行......");
    int i = 1/0;
    System.out.println("代码发生异常了......");
    } catch (Exception e) {
    System.out.println("代码发生异常后执行......");
    }
    发生异常的情况下,以上代码的执行结果是:
    1
    2
    3
    代码正常执行......
    代码发生异常后执行......

    finally代码块

  • finallytry{}catch{}体系中的一部分,全部代码书写为try{}catch{}finally{}
  • finally代码块的特点是,无论try{}中是否发生了异常,最后都会执行finally中的代码。

正常情况

1
2
3
4
5
6
7
try {
System.out.println("代码正常执行......");
} catch (Exception e) {
System.out.println("代码发生异常后执行......");
}finally {
System.out.println("finally代码块中的代码一定会执行......");
}

正常情况下,以上代码的执行结果是:

1
2
代码正常执行......
finally代码块中的代码一定会执行......

发生异常

1
2
3
4
5
6
7
8
9
try {
System.out.println("代码正常执行......");
int i = 1/0;
System.out.println("代码发生异常了......");
} catch (Exception e) {
System.out.println("代码发生异常后执行......");
}finally {
System.out.println("finally代码块中的代码一定会执行......");
}

发生异常的情况下,以上代码的执行结果是:

1
2
3
代码正常执行......
代码发生异常后执行......
finally代码块中的代码一定会执行......

try{}catch{}finally{}中的return

以上的情况都是方法是无返回值的情况,如果方法是有返回值的,并且在try{}catch{}finally{}中都有return,那么方法该return那个返回值呢?

return的位置

在探索try{}catch{}finally{}return的时机之前,我们先根据return的位置,定义一下return的类型。

1
2
3
4
5
6
7
8
9
10
11
private static String test() {
String str = "start";
try {
return str = "try ruturn"; //这里定义为正常return
} catch (Exception e) {
return str = "catch ruturn"; //这里定义为异常return
}finally {
return str = "finally ruturn"; //这里定义为最终return
}
return "method return"; //这里定义为方法return
}

return的规则

  • 最终return方法return是互斥的,即在一个方法中,最终return方法return只能写一个,否则编译无法通过(或者IDE会报错)。
  • 正常return异常return都有的时候,最终return可有可无,但是方法return一定不能有,否则报错。
  • 当有最终return的时候,正常return异常return可有可无。
  • 当没有最终return的时候,要么一定要有正常return异常return,要么一定要有方法return

return的执行顺序

当方法中return的时候,那么try{}catch{}finally{}中的代码顺序又该怎么执行呢?

首先,我们来看一下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static void main(String[] args) {
System.out.println("main:"+test());
}

private static String test() {
String str = "start";
try {
System.out.println("try:" + str);
System.out.println("try is running......");
return str = str + "->try return";
} catch (Exception e) {
System.out.println("catch:" + str);
System.out.println("catch is running......");
return str = str + "->catch return";
}finally {
System.out.println("finally:" + str);
str = "finally:" + str;
System.out.println("finally is running......");
return str = "->finally return";
}
}

该段代码的执行结果是:

1
2
3
4
5
try:start
try is running......
finally:start->try return #这里是System.out.println("finally:" + str);的输出结果,我们发现str变成了start->try return
finally is running......
main:->finally return

如果我们去掉finally中的return的话:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void main(String[] args) {
System.out.println("main:"+test());
}

private static String test() {
String str = "start";
try {
System.out.println("try:" + str);
System.out.println("try is running......");
return str = str + "->try return";
} catch (Exception e) {
System.out.println("catch:" + str);
System.out.println("catch is running......");
return str = str + "->catch return";
}finally {
System.out.println("finally:" + str);
str = "finally:" + str;
System.out.println("finally is running......");
}
}

执行结果为:

1
2
3
4
5
try:start
try is running......
finally:start->try return #这里是System.out.println("finally:" + str);的输出结果,我们发现str变成了start->try return
finally is running......
main:start->try return #这里执行了finally的代码,但是return的结果依然是try中的返回结果。

return的执行顺序分析图

在这里插入图片描述
在这里插入图片描述
如果try中发生异常,代码跳转至catch{}中执行,那么return的执行顺序和原理是和try{}中是一致的。

坚持原创技术分享,您的支持将鼓励我继续创作!
-------------这是我的底线^_^-------------