异常捕获

将系统抛出的错误信息转换为系统描述的错误,或是将异常抛出给调用当前方法的上层方法的处理方式。

核心概述

Java中通过 try...catch...语句进行异常的捕获操作,可能存在异常的代码放再 try{...} 代码块中,catch(...){...}语句中 () 记录捕获异常的类型 {...} 语句中对异常进行处理如打印日志或管理流等操作。

基础用法

try {  
    //代码逻辑
} catch (IOException e) {  
    //处理语句
}  catch (Exception e) {  
    //处理语句
} finally {
	//最终语句
}

注意

  • 捕获语句可以有多个 catch 语句,不用的 catch 语句中异常的类不同,类似于 if...else...
  • 多个 catch 语句中的异常类应注意顺序,范围小的放在前面;
  • catch 语句执行后,try...catch()... 快之后的代码不回被执行;
  • finally 语句始终会被执行,这里的代码无论是否代码一场都会被执行。

抛出异常

在一段代码中,可能会存在某些已知的错误类型或者业务逻错误。可以对该代码片段进行异常捕获,而如果需要将异常传递至调用方,需要使用 throw 关键字进行抛出。

代码示例

public class DemoThrowException {  
    public static void main(String[] args) {  
       try {  
            Integer.parseInt(null);  
        } catch (RuntimeException e) {  
            throw new RuntimeException("异常被处理");  
        }  
    }  
}

注意

  1. 使用throw 抛出异常后,异常代码块之后的代码不回直行,finally代码块除外;
  2. 异常抛出后,如果 finally 代码块中也抛出异常,则 finally 代码块中的异常会覆盖 catch 代码块中的异常
  3. try{...}catch(...){}finally{...} 执行顺序为 try->catch->finally

异常传播

某个方法中如果出现了异常,且方法内对异常没有进行捕获,异常会被抛出到上层调用方法中,直到遇见某个 try...catch... 被捕获为止。

代码示例

public static void main(String[] args) {  
    try {  
        method();  
    } catch (Exception e) {  
        e.printStackTrace();  
    }  
}  
  
public static void method(){  
    method2();  
}  
  
public static void method2(){  
    Integer.parseInt("abc");  
}
java.lang.NumberFormatException: For input string: "abc" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.lang.Integer.parseInt(Integer.java:580)
	at java.lang.Integer.parseInt(Integer.java:615)
	at learn.java.error.DemoThrowException.method2(DemoThrowException.java:23)
	at learn.java.error.DemoThrowException.method(DemoThrowException.java:19)
	at learn.java.error.DemoThrowException.main(DemoThrowException.java:12)

使用 e.printStackTrace(); 方法可以打印出异常栈信息,查看异常传递过程。

异常转换

如果方法中抛出 NUllPointException 异常,上层方法中异常捕获用了其他异常类进行捕获,则是对异常进行了转换。

代码示例

public class DemoThrowException {  
  
    public static void main(String[] args) {  
        try {  
            process1();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
  
    static void process1() {  
        try {  
            process2();  
        } catch (NullPointerException e) {  
            throw new IllegalArgumentException();  
        }  
    }  
  
    static void process2() {  
        throw new NullPointerException();  
    }  
}
java.lang.IllegalArgumentException
	at learn.java.error.DemoThrowException.process1(DemoThrowException.java:22)
	at learn.java.error.DemoThrowException.main(DemoThrowException.java:12)
 

注意: 此时丢失了最原始异常的错误信息,如果要捕获原始异常需要将捕获异常的信息带入到当前异常信息中,throw new IllegalArgumentException(e);

public class DemoThrowException {  
  
    public static void main(String[] args) {  
        try {  
            process1();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
  
    static void process1() {  
        try {  
            process2();  
        } catch (NullPointerException e) {  
            throw new IllegalArgumentException(e);  //此处差异
        }  
    }  
  
    static void process2() {  
        throw new NullPointerException();  
    }  
}
java.lang.IllegalArgumentException: java.lang.NullPointerException
	at learn.java.error.DemoThrowException.process1(DemoThrowException.java:22)
	at learn.java.error.DemoThrowException.main(DemoThrowException.java:12)
Caused by: java.lang.NullPointerException
	at learn.java.error.DemoThrowException.process2(DemoThrowException.java:27)
	at learn.java.error.DemoThrowException.process1(DemoThrowException.java:20)
	... 1 more