如何将基本异常替换为另一个异常



>我有以下代码

try {
    ....
} catch (Exception e) {
    log.error(String.format(SOME_CUSTOM_VARIABLE, e);
    throw e;
}

我希望异常SOME_CUSTOM_STRING_WITH_VARIABLES获取字符串。
所以我想做的是

try {
    ....
} catch (Exception e) {
    log.error(String.format(SOME_CUSTOM_VARIABLE, e);
    throw new Exception(SOME_CUSTOM_VARIABLE, e);
}

但这迫使我在方法签名中添加"抛出异常"。
无论如何,此方法都会引发异常。为什么我必须更改签名?

如何将基本异常替换为另一个异常?

因为引发异常意味着创建自己的方法throws Exception,因此您需要声明该方法throws它,以便该方法的用户知道catch它。 就像你一开始就不得不在试抓中包围它一样。如果没有强制声明您的方法throws那么Exception可能会丢失。

如果您不想更改方法签名,则可以创建自定义RuntimeException并抛出它。

但请注意后果:

  • 如果在上层类中未正确捕获此自定义RuntimeException,则可能会使整个程序崩溃。
  • 这更像是一种解决方法,当抛出RuntimeException时,程序不应从异常中恢复。运行时异常表示由编程问题引起的问题。

关于这方面的一些信息: https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html

但这迫使我在方法签名中添加"抛出异常"。无论如何,此方法都会引发异常。为什么我必须更改签名?

这取决于,如果你抛出检查异常,那么java编译器将强制你处理它,即你需要把它包含在方法签名中或在方法主体中处理它。
但是,如果您抛出未经检查的异常,则无需修改方法签名

我强烈建议你不要通过抛出RuntimeException来解决这个问题。这些是严格意义上的JVM专利,使用一个只是为了避免声明抛出子句将是可怕的风格。

Java 异常的名称和目的(恕我直言)令人困惑。你应该坚持这样的想法,即从Exception子类化的东西需要处理程序,而从Error派生的东西不需要。忽略破坏规则的RuntimeException,向酒吧里的同伴和 stackoverflow.com 上的随机人抱怨它应该被称为RuntimeError和子类Error(为了f**ks)。

如果你真的有一个条件,一个方法有一个 throws 子句声明一个Exception但你现在有充分的理由抛出它,那么我建议你对 UnexpectedExceptionErrorUnhandledExceptionError 进行子类Error

如果Exception"不应该是可能的",请使用第一个 - 例如一个抽象的I/O方法,你知道它由(比如)内存中的字符串支持,并且尽管有接口声明,但不能真正抛出IOException

如果抛出Exception会破坏您正在实现/覆盖的某些方法的签名,则使用第二个,这些方法无法修改以通告潜在的Exception

作为第三种方式,异常传播到run() Runnable方法是很自然的。在这些情况下,我建议将Exception传递给某个监督者流程作为一种遗书,因为无论您扔出run()什么,无论如何都会被忽略,您可能想做一些事情来识别Thread的完全失败!

PS:如果你这样做是因为你懒惰,不想正确处理异常,那么你会被诅咒维护由具有相同态度的人编写的代码:)

在 Java 中,您已经选中了异常 - 这些异常必须由抛出方法声明 - 并且未选中,这不一定是。(然后有Error的,但让我们暂时把它们放在一边)。

不详细介绍使用哪种异常策略,基本上您可以抛出任何异常,即 a 或从 RuntimeException 扩展的异常,而无需在您的方法上声明它。例如。你可以

void myMethod() { // no 'throws' declaration
    try {
        ...
    } catch (Exception e) {
        throw new RuntimeException( SOME_CUSTOM_VARIABLE , e );
    }
}

我将推荐这个SO线程和这篇博客文章,以便就该主题进行很好的讨论。

关于在throws条款中用另一个例外替换异常的问题:我知道您的方法已经抛出了一些不是专门java.lang.Exception的异常。在这种情况下,你大多不走运 - 你只能用相同或子类化的异常"替换"抛出的异常,否则你将不得不编辑/添加到throws子句。

干杯

最新更新