Java异常处理基础

1. Java异常简析

在程序运行过程中出现的错误,称为异常,异常就是程序运行过程中出现了不正常现象导致程序的中断,在Java中,把各种异常现象进行了抽象形成了异常类,如下图所示:

在这里插入图片描述

提醒:此处 RuntimeException 下的 7 个常见异常需要熟练掌握,避免滥用自定义异常!

这里着重强调:

  • Error 程序无法处理的错误,表示运行应用程序中较严重问题,一般是 JVM 出现的问题,此类异常发生时,JVM 一般会将线程终止
  • Exception 此类属于编译异常,必须编写处理的异常“方案”
  • RuntimeException 此类属于运行时异常,是程序运行时产生的,程序编写者可以编写代码对其进行处理,也可对其抛出或不处理

2. 处理异常的关键字

关键字作用及用法
try[(resource)]{work;}可能抛出异常的代码放在 try 块内,当 try 块内发生异常时,异常会被抛出,若存在 (resource) 在 try 代码块结束后会自动调用 resource.close() 方法(Java 7之后)
catch(Exception e)捕获异常 e ; catch 用来捕获 try 语句块中发生的异常,可以声明多个 catch,catch 里也可以捕捉多个异常
finallyfinally 语句块总会被执行,一般用于释放资源
throw用于抛出异常(方法体内)
throws声明该方法可能抛出的异常(方法声明)

注:[ ] 为可省略内容

特别地:

  1. 若在 catch 块中有 return 语句,则会先执行 finally 块的内容再执行 catch 块的返回语句,举个例子:该代码返回值是 3
public int getNum() {
	try {
		int a = 1 / 0;
		return 1;
	} catch (Exception e) {
		return 2;
	} finally {
		return 3;
	}
}
  1. 若 finally 中没有 return 语句,但是改变了要返回的值,若是引用类型则会改变,若是基本数据类型或字符串,则不改变

3. 异常的捕获及抛出

此部分忽略了自定义异常部分内容,将放在 SpringBoot 自定义异常部分细说

在定义方法时,如果方法体中有编译时异常需要预处理,可以捕获处理,也可以抛出处理

捕获异常注意事项

  1. 一般按照由小到大的顺序,也就是先截获子异常,再截获父异常
  • 错误范例:FileNotFoundExceptionIOException 的子类,需要放在后面,修改方法是将两个 catch 块交换位置
try{
    FileInputStream fis = new FileInputStream("test.txt");
    fis.close();
}catch(IOException e){
    e.printStackTrace();
}catch(FileNotFoundException e){
    e.printStackTrace();
}
  1. 不要捕获 Throwable 类,因为 ThrowableErrorException 的超类,系统级别错误,一般不应捕捉处理

抛出异常注意事项

子类方法的异常要比父类方法的异常更小

  • 如果父类方法没有抛出异常,子类重写后也不能抛出异常
  • 如果父类方法抛出了异常,子类方法可以抛出相同的异常,也可以抛出父类异常的子异常,也可以不抛出异常

4. 异常信息的获取

  • getMessage() 获取异常描述信息,用于打印日志
  • getCause() 获取异常的形成原因,如果是根异常则返回 null
  • printStackTrace() 取得异常的堆栈信息,用于调试阶段

注意事项

如果抛出异常的方法使用了JDK动态代理反射的方法进行执行,所有异常均会被 InvocationTargetException 所覆盖,此时需要抓取异常链获取根异常,下面给出代码模板,此方法同时适用于有在异常链不同位置均需要进行处理的情况

public static List<Throwable> getThrowableList(Throwable throwable) {
	ArrayList<Throwable> list;
	for(list = new ArrayList<>(); throwable != null && !list.contains(throwable); throwable = throwable.getCause()) {
		list.add(throwable);
	}
    return list;
}

public static Throwable getRootCause(Throwable throwable) {
	List<Throwable> list = getThrowableList(throwable);
	return list.isEmpty() ? null : list.get(list.size() - 1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值