处理线程中不受检查的异常

Java中有2类异常:

  • 受检查(Checked)异常: 必须在方法的 throws 语句中明确指出或在方法中捕获。如 IOException 或 ClassNotFoundException。
  • 不受检查(Unchecked)异常: 不需要明确指出或捕获。如 NumberFormatException。

当受检查异常在一个线程对象的 run 方法内被抛出,我们必须捕获并处理它,因为不能给 run 方法加 throws 语句。 而当不受检查异常被抛出,默认的行为是将 stack track 信息输出到控制台并退出程序。

Java 提供了在线程对象中捕获并处理不受检查的异常的机制以避免程序结束。

任务

在线程中抛出 NumberFormatException, 在主程序中捕获并处理。

实现

本节的示例代码在 com.elanzone.books.noteeg.chpt1.sect09 package中

  • 异常处理类 (ExceptionHandler)

    • 实现 Thread.UncaughtExceptionHandler 接口及 uncaughtException 方法
    public class ExceptionHandler implements Thread.UncaughtExceptionHandler {
    
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            // 输出异常信息等
        }
    
    }
    
  • 线程类 (Task)

    • 在 run 方法中产生一个异常,如转换不符合数字格式的字符串为数字
        int numero=Integer.parseInt("TTT");
    
  • 控制类 (Main)

    • 生成线程时调用线程对象的 setUncaughtExceptionHandler 方法来设置 unchecked 异常处理类
        Task task = new Task();
        Thread thread = new Thread(task);
        thread.setUncaughtExceptionHandler(new ExceptionHandler());
        thread.start();
    

工作原理

在一个线程中一个异常被抛出并未被捕获(即一个不受检查的异常)时,JVM检查线程是否有用对应方法(setUncaughtExceptionHandler)设置的未捕获异常处理器。 * 如果有: JVM将调用异常处理类的uncaughtException方法,并将线程对象和异常作为参数传递给此方法。 * 如果没有: JVM将stack trace输出到控制台并退出程序。

了解更多

Thread 类有另一个方法和未捕获异常的处理有关。就是静态方法 setDefaultUncaughtExceptionHandler(),它为应用程序中的所有线程对象设置一个异常处理器。

当线程中有一个未捕获被抛出时,JVM按以下顺序查找此异常的3种可能的处理器:

  1. 使用本节介绍的方法设置的
  2. 使用线程对象所在ThreadGroup里设置的
  3. 缺省的(输出stack trace到控制台并退出程序)