Try-catch-finally的执行顺序以及程序何时终止
文章目录
异常的分类
异常分为运行时异常和非运行时异常(IOException,SQLException,自定义异常)
如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。
如果不想终止,则必须捕获所有的运行时异常,决不让这个处理线程退出。队列里面出现异常数据了,正常的处理应该是把异常数据舍弃,然后记录日志。不应该由于异常数据而影响下面对正常数据的处理。
非运行时异常是RuntimeException以外的异常,类型上都属于Exception类及其子类。如IOException、SQLException等以及用户自定义的Exception异常。对于这种异常,JAVA编译器强制要求我们必需对出现的这些异常进行catch并处理,否则程序就不能编译通过。所以,面对这种异常不管我们是否愿意,只能自己去写一大堆catch块去处理可能的异常
不对异常进行处理
@Test
public void test() {
User user = new User();
System.out.println(user.getAge().byteValue());
// 不对异常进行处理,出现运行时异常程序终止
System.out.println("运行时异常程序终止吗");
}
执行结果:
对于运行时异常进行try-catch
@Test
public void test1() {
User user = new User();
try {
System.out.println(user.getAge().byteValue());
} catch (Exception e) {
e.printStackTrace();
}
// try-catch后程序不会终止
System.out.println("运行时异常程序终止吗");
}
catch块中增加return语句,return语句会导致程序终止
@Test
public void test2() {
User user = new User();
try {
System.out.println(user.getAge().byteValue());
} catch (Exception e) {
e.printStackTrace();
return;
}
// catch块中存在return程序终止
System.out.println("运行时异常程序终止吗");
}
throws的运行时异常需要进行try-catch
IOException、SQLException异常以及用户自定义异常不进行try,catch则不允许编译。
@Test
public void test3() {
File file = new File("a.txt");
if(!file.exists()){
// IOException、SQLException异常以及用户自定义异常不进行try,catch则不允许编译。
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
手动抛出异常程序终止
@Test
public void test4() {
User user = new User();
user.setName("方庆");
System.out.println(user.getName());
// 手动抛出异常程序直接终止
throw new BadException("出现重大错误");
// 直接编译错误,代码块并不能到达此处
// System.out.println("直接抛出异常程序会终止吗");
}
catch块抛出异常finally块还会执行
@Test
public void test5() {
try {
int i = 1 / 0;
} catch (Exception e) {
e.printStackTrace();
throw new BadException("出错");
} finally {
// 会执行
System.out.println("catch抛出异常finally块还会执行吗");
}
}
finally块中有return不会执行catch块中的手动抛出异常
@Test
public void test6() {
try {
int i = 1 / 0;
} catch (Exception e) {
e.printStackTrace();
throw new BadException("出错");
} finally {
// finally块执行return,则catch块中的throw不会执行,所以throw相当于return。
System.out.println("catch抛出异常finally块还会执行吗");
return;
}
}
try-catch-finally块同时存在return
catch到异常后便不会执行catch块后面的代码,所以catch的代码块要尽量小而精确
try-catch-finally同时存在return,
try块代码=>在执行catch块代码=>在执行finally块代码=>在执行finally块return,catch=>return
public void test7() {
try {
System.out.println("抛出异常前");
int i = 1 / 0;
System.out.println("抛出异常后");
return;
} catch (Exception e) {
e.printStackTrace();
System.out.println("进入catch块");
return;
} finally {
System.out.println("进入finally块");
return;
}
}
执行结果:
@Test
public void test7() {
try {
System.out.println("抛出异常前");
int i = 1 / 0;
System.out.println("抛出异常后");
return;
} catch (Exception e) {
e.printStackTrace();
System.out.println("进入catch块");
} finally {
System.out.println("进入finally块");
}
System.out.println("走出异常");
}
执行结果:
# 总结
- throw手动抛出异常相当于return,程序终止
- 不对异常进行try-catch,程序出现非运行时异常程序终止
- try-catch-finally执行循序,try块代码 -> catch块代码 -> finally块代码 -> finally块return -> catch块return