关于java:如何重新抛出异常

How to re-throw an exception

在我的onCreate()中,我设置了一个未捕获的异常处理程序,如下所示:

1
2
3
4
5
6
7
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {
       Log.e(getMethodName(2),"uncaughtException", throwable);
       android.os.Process.killProcess(android.os.Process.myPid());
    }
});

它工作正常,但我想恢复系统向用户显示强制关闭对话框的默认行为。

如果我试图用throw throwable替换KillProcess()调用,编译器会抱怨我需要用try/catch来包围它。

如果我用一个尝试/捕获包围它:

1
2
3
4
5
6
7
8
9
10
11
12
13
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {
        try {
            Log.e(getMethodName(2),"uncaughtException", throwable);
            throw throwable;
        }
        catch (Exception e) {          
        }
        finally {              
        }
    }
});

编译器仍然抱怨throw throwable需要用try/catch包围。

我该怎么再扔那个废物?这样,除了信息丰富的Log.e()之外,系统的行为与以前完全一样:我从未设置默认的未捕获异常处理程序。


尝试:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class CustomExceptionHandler implements UncaughtExceptionHandler {

    private UncaughtExceptionHandler defaultUEH;

    public CustomExceptionHandler() {
        this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
    }

    public void uncaughtException(Thread t, Throwable e) {
        Log.e("Tag","uncaughtException", throwable);
        defaultUEH.uncaughtException(t, e);
    }
}

然后Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler());

根据这个答案改编。


如果设置默认的未捕获异常处理程序,则需要使用其中的异常。这反映在uncaughtException没有宣布任何例外。

不应该有明显的理由再扔它。它将第二次打印在日志中,线程将无论如何死亡。如果你真的想这样做,那就用RuntimeException包起来再扔。


根据JavaDoc的说法,没有理由重新抛出可丢弃的代码,它只是被忽略了。线程将在此时终止,您只需设置退出前要尝试的最后操作。

为了争论的目的,如果你真的想重新抛出一个可丢弃的,你应该做如下的事情:

1
2
3
4
5
6
7
8
9
public void reThrow(Throwable t) {
    if (RuntimeException.class.isAssignableFrom(t.getClass())) {
        throw (RuntimeException)t;
    } else if (Error.class.isAssignableFrom(t.getClass())) {
        throw (Error) t;
    } else {
        throw new UndeclaredThrowableException(t);
    }
}


首先,您不需要重新抛出异常。uncaughtException()不使用异常。但是,您必须调用默认的未捕获异常处理程序的方法。就像,

1
2
3
4
5
6
7
8
class MyUEH implements UncaughtExceptionHandler {
  private static final UncaughtExceptionHandler default = Thread.getDefaultUncaughtExceptionHandler();

    public void uncaughtException(Thread t, Throwable e) {
        Log.e("Tag","uncaughtException", throwable);
        default.uncaughtException(t, e);
    }
}

第二,你不需要自己扼杀这个过程。当您调用它时,默认的UEH将处理这个问题。

第三,默认的UEH将向用户显示(或导致显示)标准崩溃(强制关闭)对话框。请记住,如果您的方法挂起(例如,因为您正在执行IO),那么在您的方法退出之前,用户将看不到崩溃对话框。