Java 异常
什么是异常
- 异常本质上是程序上的错误。
- 错误在我们编写程序的过程中会经常发生,包括编译期间和运行期间的错误。
- 在程序运行过程中,意外发生的情况,背离我们程序本身的意图的表现,都可以理解为异常。
Throwable(异常的根类)
- Error(Java 虚拟机出现问题)
- Error 是程序无法处理的错误,表示运行应用程序中比较严重的问题。
- 它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。
- 对于设计的合理的应用程序来说,即使确实发生了错误,本质上也不应该试图去处理它所引起的异常状况。
- 常见错误
- 虚拟机错误 VirtualMachineError
- 内存溢出 OutOfMemoryError
- 线程死锁 ThreadDeath
- Exception
- Exception 是程序本身可以处理的异常。异常处理通常指针对这种类型异常的处理。
- 检查异常 Checked Exception
- 编译器要求必须处置的异常。(编码阶段)
- 除了 RuntimeException 及相关子类,其它异常都属于 Checked Exception
- IO 异常 IOException
- SQL 异常 SQLException
- 等等
- 非检查异常 Unchecked Exception
- 编译器不要求强制处置的异常(运行阶段)
- 包含 RuntimeException 及相关子类
- 空指针异常 NullPointerException
- 数组下标越界异常 ArrayIndexOutOfBoundsException
- 算数异常 ArithmeticException
- 类型转换异常 ClassCastException
- 等等…
- System.exit(1); 终止程序运行
throw & throws
- throws
- 可以通过 throws 声明将要抛出何种类型的异常,通过 throw 将产生的异常抛出。
- 如果一个方法可能出现异常,但没有能力处理这种异常,可以在方法声明处用 throws 子句来声明抛出异常。
- throws 语句用在方法定义时声明该方法要抛出的异常类型。
- 当方法抛出异常列表中的异常时,方法将不对这些类型及其子类类型的异常做处理,而抛向调用该方法的方法,由他去处理。
- throw
- throw 用来抛出一个异常。
- 例如:throw new IOException():
- thorw 抛出的只能够是可抛出类 Throwable 或者其子类的实例对象。
- 例如:throw new String(“出错了”); 是错误的
1
2
3
4
5
6
7
8
9
10
11
12public void method(){
try{
// 代码段1
throw new 异常类型();
}catch(异常类型 ex){
// 对异常处理的代码段2
}
}
public void method() throws 异常类型{
// 代码段1
throw new 异常类型();
}
- 例如:throw new String(“出错了”); 是错误的
- 作用
- 规避可能出现的风险
- 完成一些程序的逻辑
- throw 抛出异常对象的处理方案
- 通过 try…catch 包含 throw 语句 —— 自己抛出自己处理
- 通过 throws 在方法声明抛出异常类型 —— 谁调用谁处理 —— 调用者可以自己处理,也可以继续上抛。此时可以抛出与 throw 对象相同类型或者其父类
- 当子类重写父类抛出异常方法时,声明的异常必须是父类方法所声明异常的同类或子类。
- throw 用来抛出一个异常。
自定义异常
- 基本概念
- 使用 Java 内置的异常类可以描述在编程时出现的大部分异常情况。
- 也可以通过自定义异常描述特定业务产生的异常类型。
- 所谓自定义异常,就是定义一个类,去继承 Throwable 类或者它的子类
1
2
3
4
5
6
7
8
9
10public class TestException extends Exception{
public TestException(){
super("向父类抛的异常消息");
}
}
public static void test() throw TestException{
<代码块>
throw new TestException();
}
异常链
- 基本概念
- 有时候我们会捕获一个异常后在抛出另一个异常
- 顾名思义就是:将异常发生的原因一个传一个串起来,即把底层的异常信息传个上层,这样逐层抛出。
- Exception e1 = new Exception(“异常消息”); e1.initCause(e);
如何处理异常
- 在 Java 应用程序中,异常处理机制为
- 抛出异常(先抛出,才能被捕获)
- 捕获异常
- 对于运行时异常,错误或可检查异常,Java 技术所要求的异常处理方式有所不同。
- 1、对于可查异常必须捕捉、或者声明抛出
- 2、允许忽略不可查的 RuntimeException(含子类)和 Error(含子类)
- 通过 5 个关键字来实现
- 捕获异常
- try(执行可能产生异常的代码)
- catch(捕获异常)
- finally(无论是否发生异常 代码总能执行)
- 声明异常
- throws(声明可能要抛出的异常)
- 抛出异常
- throw (手动抛出异常)
- 捕获异常
- 规则说明
- try-catch-finally
- try 块后可接零个或多个catch块,如果没有 catch 块,则必须跟一个finally块。
- try-catch-finally
- 自定义异常
- 异常链
实际应用总结
- 处理运行异常时,采用逻辑去合理规避同时辅助 try-catch 处理
- 在多重 catch 块后面,可以加一个 catch(Exception) 来处理可能被遗漏的异常
- 对于不确定的代码,也可以加上 try-catch,处理潜在的异常
- 尽量去处理异常,切忌知识简单的调用 printStackTrace() 去打印输出
- 具体如何处理异常,要根据不同的业务需求和异常类型去决定
- 尽量添加 finally 语句块去释放占用的资源(关闭文件、关闭 sql 链接)等