异常 - 继承

Exceptions - inheritance

假设我定义了自己的异常(例如'MyException'),并且还有这些方法:

    public String myMethod3() throws MyException {

    try {
        methodThatAlwaysThrowsException();
    } catch (Exception e) {
        MyException me = new MyException("Exception!");
        throw me;
    }

    return "myMethod3";
}

public String myMethod2() throws MyException {

    String str = myMethod2();
    return "myMethod2 " + str;
}

public void myMethod1() {

    String str = null;

    try {
        str = myMethod2();
    } catch (MyException e) {
        e.printStackTrace();
        str = "Exception caught";
    }

    System.out.println(str);
}

我是否理解正确,当在 'methodThatAlwaysThrowsException' 中抛出异常时,它将被捕获并抛出 MyException。然后 MyMethod2() 会再次将它扔回 myMethod1() 来捕获它,然后 'Exception caught' 会被写入?

更具体地说,当方法中抛出错误时,方法 'above' 也只是抛出错误,只有 try/catch(或主要方法抛出它)?我正在查看一些具有深层层次结构的代码,其中可能会抛出异常 5-6-7 方法,然后被捕获。这是处理异常的好方法吗?对我来说,似乎应该立即发现错误。像这样扔它们有充分的理由吗?

这真的取决于组件以及抛出异常的原因,这里有几个例子说明在不同情况下如何处理异常。

别抓到它

在RESTful应用程序中你可以注册ExceptionMapper,每个抛出的异常都会被传递到这个class并根据映射器如何处理这个异常转换成响应。因此,如果我们不关心(不期望)异常,我们就不会捕获它。如果是checked exception,我们将其转换为RuntimeException并重新抛出。

忽略它

假设我们有一个服务器端缓存来避免对数据库的昂贵访问。缓存每 5 分钟更新一次。如果刷新失败,我们仍然想在 5 分钟后重试,在这种情况下我们只记录异常但不在 catch 块中执行任何其他操作。

处理它

如果你想处理异常,我建议尽快处理。例如,GUI 应用程序试图覆盖现有文件,但它失败了(可能文件被另一个进程锁定)。我们可能有一项功能,在这种情况下将其保存到不同的文件中。在这种情况下,您越早捕获异常,代码就越容易理解 - 因为您不必浏览 5 个文件来找出这个异常发生了什么。

More specifically, when an error is thrown in a method, and the methods 'above' it also just throws the error, it won't be caught until you have a try/catch (or the main method throws it)?

是的。阅读下面来自 JLS §11.3. Run-Time Handling of an Exception 的内容以及来自 link 的更多内容......

所以:

  • 如果您不捕获异常,则异常将传播到主线程,主线程将终止。
  • 如果您捕获到异常并重新抛出它,那么将执行该方法中的后续代码块(请阅读 JLS link 我提供的更多详细信息)。
  • 如果您捕获异常并重新抛出它,那么它将传播到该方法的调用者。

来自 JLS:

If no catch clause that can handle an exception can be found, then the current thread (the thread that encountered the exception) is terminated. Before termination, all finally clauses are executed and the uncaught exception is handled

When an exception is thrown (§14.18), control is transferred from the code that caused the exception to the nearest dynamically enclosing catch clause, if any, of a try statement (§14.20) that can handle the exception.


您的问题:

Is this a good way to handle Exceptions?

是的,应使用 try-catch-finally

处理异常

To me it seems like the error should be caught right away. Is there a good reason to throw them like this?

是的,您应该重新抛出它,以便它可以被 DynaTrace 等应用程序性能监控 (APM) 工具捕获。如果您捕获异常并简单地吃掉它,那么这些 APM 工具将无法找到它,因此不会生成任何报告。

因此,从应用程序性能监控 (APM) 工具的角度来看,抛出异常是一种很好的做法,您可以再次捕获它并做任何您想做的事情,但是抛出它一次。