概述

有时候我们在处理异常的时候不是每次都把它 throws 掉就完事了,很多时候异常是需要我们自己来 catch 并针对所抛出的 Exception 做一些后续的处理工作。

我们在面试的时候。经常会遇到这样的面试题目:

  • 1、try体异常抛出。catch 体里遇到 return 并且没有finally体。是怎么处理?
  • 2、try体不抛异常。catch 体里遇到 return 并且没有finally体。是怎么处理?
  • 3、try体不抛异常。并且有finally体有return语句。是怎么处理?
  • 4、try体抛出异常。并且有catch体和finally体都有return语句。是怎么处理?
  • 5、System.exit() 语句怎么处理??

下面我们来讲讲上面这些面试题。

1、try体异常抛出。catch 体里遇到 return 并且没有finally体。是怎么处理?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 /**
* try体异常抛出。catch 体里遇到 return 并且没有finally体。
*/
private static boolean catchReturnTest() {
try {
System.out.println("try body called");
int i = 10 / 0; // 抛出 Exception,后续处理被拒绝
System.out.println("i vaule is : " + i);
return true; // Exception 已经抛出,没有获得被执行的机会
} catch (Exception e) {
System.out.println(" -- Exception Catch--" + e);
System.out.println("catch body called ");
return false; // Exception 抛出,获得了调用方法并返回方法值的机会
}
}

输出结果:
try body called
-- Exception Catch--java.lang.ArithmeticException: / by zero
catch body called
catchReturnTest = [false]

结论:try体异常抛出。catch 体里遇到 return 并且没有finally体。那么try体异常之后的代码不再执行。直接执行catch体里面的代码。然后执行catch里面的return语句。

2、try体不抛异常。catch 体里遇到 return 并且没有finally体。是怎么处理?

结论:try体不抛异常。catch 体里面的代码不会执行。返回catch体里面的return语句也不会执行。

3、try体不抛异常。并且有finally体有return语句。是怎么处理?
直接看代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    /**
* try体不抛异常。并且有finally体有return语句。是怎么处理?
* @return
*/
private static String finallyReturnTest() {
try {
System.out.println("try body called");
int i = 10 / 2; // 不抛出 Exception
System.out.println("i vaule is : " + i);
return "try body return"; // 获得被执行的机会,但执行需要在 finally 执行完成之后才能被执行
} catch (Exception e) {
System.out.println(" -- Exception --");
System.out.println("catch body called ");
return "catch body return";
} finally {
System.out.println("finally body called ");
return "finally body return"; // finally 中含有 return 语句,这个 return 将结束这个方法,不会在执行完之后再跳回 try 或 catch 继续执行,方法到此结束,返回 false
}
}

输出结果:
try body called
i vaule is : 5
finally body called
finallyReturnTest = [finally body return]

结论:try体里面没有异常抛出。那么catch体里面的代码就不会被执行。直接执行完try体。然后执行finally体。返回finally里面的返回值。

直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
   private static String catchAndFinallyReturnTest() {
try {
System.out.println("try body called");
int i = 10 / 0; // 抛出异常
System.out.println("i vaule is : " + i);
return "try body return"; //不会获得执行机会
} catch (Exception e) {
System.out.println(" -- Exception --");
System.out.println("catch body called ");
return "catch body return";
} finally {
System.out.println("finally body called ");
return "finally body return"; // finally 中含有 return 语句,这个 return 将结束这个方法,不会在执行完之后再跳回 try 或 catch 继续执行,方法到此结束,返回 "finally body return"
}

执行结果:
try body called
-- Exception --
catch body called
finally body called
catchAndFinallyReturnTest = [finally body return]

结论:try体里面如果有异常抛出,异常之后的代码不会再执行。并且catch体里面的代码就会被执行。再执行执行finally体。返回finally里面的返回值。

5、System.exit() 语句怎么处理??

直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
     private static String finallyExitTest() {
try {
System.out.println("try body called");
// System.exit(0);// System.exit() 语句,System.exit() 将退出整个程序,程序将被终止
int i = 10 / 0; // 抛出异常
System.out.println("i vaule is : " + i);
return "try body return"; // 获得被执行的机会,但执行需要在 finally 执行完成之后才能被执行
} catch (Exception e) {
System.out.println(" -- Exception --");
System.out.println("catch body called ");
// System.exit(0);// System.exit() 语句,System.exit() 将退出整个程序,程序将被终止
return "catch body return";
} finally {
System.out.println("finally body called ");
System.exit(0);// finally 中含有 System.exit() 语句,System.exit() 将退出整个程序,程序将被终止
return "finally body return"; // 不会执行。System.exit() 将退出整个程序,程序将被终止
}
}
输出结果:
try body called
-- Exception --
catch body called
finally body called

综上所述:
别看场景分的挺多。其实就是总结最根本的一点:

  • 如果有System.exit(0)语句。能执行到System.exit(0)语句的时候。程序直接退出。
  • 没有System.exit(0)语句的话,如果有finally语句。则finally语句一定都会执行,如果finnaly有返回值。则返回finally体的返回值。如果没有返回值,则执行完所有finnal语句之后。则能执行到catch就返回catch。不能就返回try体的返回值。
  • 没有finally体的话。异常就返回catch体的返回值。没有异常就返回try体的返回值。