1. 抛出异常后的代码执行情况
下面使用三段代码进行测试
代码1
public static void test1() throws Exception {
throw new Exception("参数越界");
System.out.println("异常后"); //编译错误,「无法访问的语句」
}
代码2
public static void test2() throws Exception {
try {
throw new Exception("参数越界");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("异常后"); // 可以执行
}
代码3
public static void test3() throws Exception {
if (true) {
throw new Exception("参数越界");
}
System.out.println("异常后"); //抛出异常,但不会执行
}
代码4
public static void test4() throws Exception {
try{
throw new Exception("参数越界");
}catch (Exception e){
System.out.println("catch");
return;
}
System.out.println("异常后"); // 编译错误,「无法访问的语句」
}
总结:
- 若一段代码前有异常抛出,并且这个异常没有被捕获,这段代码将产生编译时错误「无法访问的语句」。如代码1
- 若一段代码前有异常抛出,并且这个异常被try…catch所捕获,若此时catch语句中没有抛出新的异常,则这段代码能够被执行,否则,同第1条。如代码2
- 若在一个条件语句中抛出异常,则程序能被编译,但后面的语句不会被执行。如代码3
- 若cath语句中使用return ,则如果有异常抛出, 被catch 捕捉到, 那么后面的语句都不会被执行, 并且会抛出编译错误 ,如代码4
2. Java中try catch finally语句中含有return语句的执行情况
首先, 不建议在 finally 语句块中使用 return 语句, 因为 finally块中的内容会先于try中的return语句执行,如果finall语句块中也有return语句的话,那么直接从finally中返回了
对于含有return语句的情况,这里可以简单地总结如下:
try语句在返回前,将其他所有的操作执行完,保留好要返回的值,而后转入执行finally中的语句,而后分为以下三种情况:
1. 情况一:
如果finally中有return语句,则会将try中的return语句”覆盖“掉,直接执行finally中的return语句,得到返回值,这样便无法得到try之前保留好的返回值。
2. 情况二:
如果finally中没有return语句,也没有改变要返回值,则执行完finally中的语句后,会接着执行try中的return语句,返回之前保留的值。
3. 情况三:
如果finally中没有return语句,但是改变了要返回的值,这里有点类似与引用传递和值传递的区别,分以下两种情况:
1)如果return的数据是基本数据类型或文本字符串,则在finally中对该基本数据的改变不起作用,try中的return语句依然会返回进入finally块之前保留的值。
2)如果return的数据是引用数据类型,而在finally中对该引用数据类型的属性值的改变起作用,try中的return语句返回的就是在finally中改变后的该属性的值。