1. Java异常
程序运行过程中,往往会遇见各种各样的异常:文件找不到、网络连接失败、非法参数等,Java通 过API中Throwable类的众多子类描述各种不同的异常。
Java异常都是对象,是Throwable子类的实例,描述了出现在一段编码中的错误条件。当条件生成时,错误将引发异常。
所有的异常都有一个共同的祖先 Throwable(可抛出)。Throwable 指定代码中可用异常传播机制通过 Java 应用程序传输的任何问题的共性
Throwable有两个子类:
- Error(错误):是程序无法处理的错误,表示运行应用程序中较严重问题。
- Exception(异常):是程序本身可以处理的异常。Exception有一个重要的子类 RuntimeException,表示“JVM 常用操作”引发的错误。例如,若试图使用空值对象引用、除数为零或数组越界。异常又分为:
- 可查的异常(checked exceptions):编译器要求必须处置的异常,正确的程序在运行中,很容易出现的、情理可容的异常状况,一旦发生这种异常状况,就必须采取某种方式进行处理。
- 不可查的异常(unchecked exceptions):除了RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常。这种异常的特点是Java编译器会检查它,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。不可查异常又包含以下两种:
- 运行时异常 / 不检查异常(Unchecked Exception):RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过,一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
- 编译异常 / 检查异常(Checked Exception):类型上都属于Exception类及其子类,必须进行处理才能编译通过,如IOException、SQLException等以及用户自定义的Exception异常。
2. 关键字解释
try…catch关键字:
try/catch代码块中的代码称为保护代码,语法如下:
try{
//(尝试运行的)程序代码
}catch(异常类型 异常的变量名){
//异常处理代码
}finally{
//异常发生,方法返回之前,总是要执行的代码
}
Catch 语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try 后面的 catch 块就会被检查。如果发生的异常包含在 catch 块中,异常会被传递到该 catch 块,这和传递一个参数到方法是一样。
throws/throw 关键字:
throws 关键字:放在方法签名的尾部,用于声明该方法可能会抛出异常,当出现了编译异常(检查异常),就必须处理或者重新抛出该异常
throw关键字:用来抛出Throwable类型的异常,如是编译异常(检查异常),这个方法也需要声明可能抛出某异常。
举个栗子:
public static void test() throws Exception{
//抛出一个检查异常
throw new Exception("方法test中的Exception");
}
finally关键字:
无论是否发生异常,finally 代码块中的代码总会被执行。在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。
Throwable常用方法:
getCause():返回抛出异常的原因。如无原因则返回 null。
getMessage():返回异常的消息信息
printStackTrace():对象的堆栈跟踪输出至错误输出流,作为字段 System.err 的值。
3. 处理异常机制
- 抛出异常:当一个方法引发异常时,该方法会将出现的异常信息封装为异常对象,运行时寻找处理异常的代码并执行,任何代码都可以通过throw抛出异常。
- 捕获异常:当异常被抛出时,运行时系统会寻找合适的异常处理器(当异常处理器所能处理的异常类型与方法抛出的异常类型相符)用来处理该异常
举个栗子: 捕捉throw语句抛出的“除数为0”异常
public class TestException {
public static void main(String[] args) {
int a = 6;
int b = 0;
try { // try监控区域
if (b == 0) throw new ArithmeticException(); // 通过throw语句抛出异常
System.out.println("a/b的值是:" + a / b);
}
catch (ArithmeticException e) { // catch捕捉异常
System.out.println("程序出现异常,变量b不能为0。");
}
System.out.println("程序正常结束。");
}
}