在开发过程中总会遇到各种各样的异常,比如最常见的空指针异常、数组越界异常等。这些异常是指在方法不能按照正常方式完成时,可以通过抛出异常的方式退出该方法,在异常中封装了方法执行过程中的错误信息及原因,调用方在获取该异常后可根据业务的情况选择处理该异常或者继续抛出该异常。异常直接影响到程序的健壮性和系统的稳定性,而异常的处理机制的好坏也代表着一门计算机语言的健壮性的好坏,Java作为一门有着优秀的健壮性的语言,自然有着完善的异常机制,而作为开发人员了解全面的异常处理机制以及对异常进行良好的处理至关重要。
在Java中,Throwable是所有错误或异常的父类,Throwable又可分为Error和Exception,常见的Error有AWTError、ThreadDeath, Exception又可分为RuntimeException和CheckedException。如下为Java中的异常处理类的结构图:
Error 类是指 java 运行时系统的内部错误和资源耗尽错误。应用程序不会抛出该类对象。如果出现了这样的错误,除了告知用户,剩下的就是尽力使程序安全的终止。一般这种我们不会在程序中处理这种错误。
RuntimeException:指在Java虚拟机正常运行期间抛出的异常,RuntimeException可以被捕获并处理,如果出现RuntimeException,那么一定是程序发生错误导致的。我们通常需要抛出该异常或者捕获并处理该异常。常见的RuntimeException有NullPointerException、ClassCastException等。
CheckedException:指在编译阶段Java编译器会检查CheckedException异常并强制程序捕获和处理此类异常,即要求程序在可能出现异常的地方通过try catch语句块捕获并处理异常。常见的CheckedException有由于I/O错误导致的IOException、SQLException、ClassNotFoundException等。该类异常一般由于打开错误的文件、SQL语法错误、类不存在等引起。
一般需要我们处理的为Exception,异常处理方式有抛出异常和使用try catch语句块捕获并处理异常这两种方式。
抛出异常:遇到异常时不进行具体处理,而是将异常抛给调用者,由调用者根据情况处理。有可能是直接捕获并处理,也有可能是继续向上层抛出异常。抛出异常有三种形式:throws、throw、系统自动抛出异常。其中,throws作用在方法上,用于定义方法可能抛出的异常;throw作用在方法内,表示明确抛出一个异常。具体的使用方法如下:
public static void main(String[] args) {
String s = "abc";
if(s.equals("abc")) {
throw new NumberFormatException();
} else {
System.out.println(s);
}
}
public int div(int a,int b) throws Exception{
return a/b;
}
throws作用于方法上,后面可以跟多个可能抛出的异常,用于声明方法在运行过程中可能出现的异常,以便调用者根据不同的异常类型预先定义不同的处理方式;throw作用于方法内部,后面跟的是具体的异常对象,用来抛出封装了异常信息的对象,程序在执行到throw时后续的代码将不再执行,而是跳转到调用者,并将异常信息抛给调用者。也就是说,throw后面的语句块将无法执行,finally语句块除外。
除了抛出异常之外,我们还可以使用try catch语句处理异常,比如下面的方法,如果字符串转换为整数异常,则返回一个默认的数值-1,代码如下:
private int parseStrToInt(String numberStr){
int number = 0;
try{
number = Integer.parseInt(numberStr);
}catch (NumberFormatException e) {
number = -1;
}
return number;
}