文章目录
问题1:try/catch/finally执行顺序问题
1.代码
- 问下述代码能否编译通过?如果能,输出是?
public class Demo03 {
public static void main(String[] args) {
try {
String s = null;
return;
}catch (Exception e){
System.out.println("catch");
}finally {
System.out.println("finally");
}
}
}
2.分析
-
上述代码可以编译通过,输出
finally
-
这其实很简单,进入try代码块,执行
return
前的内容,然后没有发生异常则进入到finally
代码块中的内容,然后再执行return
3.问题1.1
- 下述代码能否编译通过?输出是?
public class Demo03 {
public static void main(String[] args) {
try {
String s = null;
System.exit(0);
// return;
}catch (Exception e){
System.out.println("catch");
}finally {
System.out.println("finally");
}
}
}
-
可以编译通过,什么都不输出
-
注意到代码
System.exit(0);
,遇到它的时候就不会再去执行finally
中的代码,而是直接退出程序,这表示结束正在运行中的虚拟机 -
一般来说
finally
中的代码是一定会被执行的,但是这是唯一的特殊情况,因为虚拟机都没了,后面的代码肯定都没办法执行
问题2:两类异常的不同处理方式
运行期异常,编译期异常
1.问题引入
- 下述代码能否编译通过
public class ExceptionTest {
public void doSomething() throws ArithmeticException{
System.out.println("do");
}
public static void main(String[] args) {
ExceptionTest test = new ExceptionTest();
test.doSomething();
}
}
-
可以通过,
ArithmeticException
是一个运行期异常,可以对其不做处理,最后会被抛出到虚拟机中处理 -
下述代码能否编译通过?
public class ExceptionTest {
public void doSomething() throws IOException {
System.out.println("do");
}
public static void main(String[] args) {
ExceptionTest test = new ExceptionTest();
test.doSomething();
}
}
-
不能,
IOException
是一个编译期异常, 必须显式的向上抛出
-
修改上述代码,可以编译通过
2小结
上述问题的本质是对于两种不同异常处理方式
checked exception
:编译期异常,都是java.lang.Exception
的子类,必须进行处理,有两种处理方式- 继续向上抛出,消极的做法,直到跑到JVM
- 主动的用
try...catch
进行处理
unchecked exception
:运行期异常,都是java.lang.RuntimeException
的子类,可以不出力
2.1异常类的继承结构
那我们如何能区分哪些异常属于编译期异常,哪些属于运行期异常呢?
问题3:try…catch捕获异常时的顺序问题
异常范围大的放下面,范围小的放前面
1问题
- 下述代码,编译能否通过
public class ExceptionTest2 {
public void doSomething01() throws IOException{
System.out.println("do");
}
public static void main(String[] args) {
ExceptionTest2 test = new ExceptionTest2();
try {
test.doSomething01();
} catch (Exception e) {
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
}
}
-
不能
-
第一个
catch
是所有异常类的父类,不管try
中发生何种异常都会进入到第一个catch
的代码块中 -
而只要进入了一个
catch
后面所有的catch
就不会再被进入了,所有发生了编译错误 -
当使用多个
catch
来捕获异常的时候一定要注意范围问题:异常范围大的放下面,范围小的放上面 -
调整顺序后,编译通过
-
一般情况下,我们一般只用一个
catch
来捕获Exception
类的异常即可