要想写出一个好的系统,异常是绕不开的一个结。所谓天有不测风云,人有旦夕祸福。一个系统运转的时候总是“多灾多难”的,特别是真实的用户,往往不会按照程序设计者的思路出牌。如果没有异常的处理,程序的健壮性基本为零,用户体验极差,这样的程序是使用不了的。
一、异常的分类
java中的异常都继承自Throwable,而需要程序员处理的只有Exception,我们不需要去管Error那部分。Exception又分为RuntimeException(运行时异常)和CheckedException,后者不做处理,在编译时就会抛出。所以往往出问题的就是编程是不易发现的,但是又跟业务息息相关的RuntimeException。
如何应对呢?
我们先从最基础的开始说起。
try{
//...业务实现
}catch (SubException1 e1){
//...异常处理模块1
}catch (SubException2 e2){
//...异常处理模块2
}
//...其他异常处理模块
finally {
//...回收资源,除非try,catch模块中有退出虚拟机的方法,否则finally一定会执行
}
这是最普通的异常处理方式try...catch...finally...,逐个catch异常,最后回收资源。注意的一点是异常父类要写在异常子类下面。
还有一种特殊的写法,java7的自动关闭资源的try语句。
FileInputStream fis = null;
try{
fis = new FileInputStream("test.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally {
if (fis != null){
fis.close();
}
}
在java7之前finally中的代码是不得不写的,java7之后改变了这种形式
try( //声明初始化两个可关闭的资源
//try语句会自动关闭这两个资源
BufferedReader br = new BufferedReader(new FileReader("test.txt"));
PrintStream ps = new PrintStream(new FileOutputStream("test.txt"))
){
System.out.println(br.readLine());
System.out.println("test opening test.txt");
}
try后面加上加上小括号,括号里面可以声明,初始化一个或者多个必须在程序结束时显式关闭的资源(比如数据库连接,网络连接等)。这些资源必须实现AutoCloseable或Closeable接口,也就是要实现close()方法。
二、空指针异常
空指针异常(NullPointerException)是最常见的RuntimeException。一般而言在参数前面加个判断就可以解决了。
if (list != null && list.size() > 0) {
//TODO
}
三、自定义异常
一般是以下四种方式
public class MyException extends Exception {
//无参数
public MyException(){
super();
}
//指定信息
public MyException(String msg){
super(msg);
}
//指定原因和信息
public MyException(String msg,Throwable casue){
super(msg,casue);
}
//指定原因
public MyException(Throwable cause){
super(cause);
}
}
抛出异常
public class ExceptionTest {
public void getException(int a) {
try {
if (a > 0){
throw new MyException("a is bigger than zero");
}
}catch (MyException e){
//TODO
}
}
}
在使用的过程中,我们的异常要处理之后向上抛出,有些可能需要集中处理然后展示给用户看。
改动下代码:
public class ExceptionTest {
public void getException(int a) throws MyException{
try {
if (a > 0){
throw new MyException("a is bigger than zero");
}
}catch (MyException e){
throw new MyException("a大于零");
}
}
}
测试
public class ExceptionDriver {
public static void main(String[] args) {
ExceptionTest exceptionTest = new ExceptionTest();
try {
exceptionTest.getException(3);
} catch (MyException e) {
System.out.println("异常错误");
}
}
}
结果: