RuntimeException应该被扩展吗?

3

这更像是一个面向对象设计的问题。

我有一个UnsuportedLocaleException,它只会在应用程序的初始化阶段使用。我有两个选项:

  1. 继承RuntimeException并使其不带任何处理逻辑(作为配置 => 如果错误,则应用默认值)。
  2. 继承Exception并处理它(涉及所有冗余编码等)。

我更喜欢第一个选项,但不确定是否正确的设计。


重复的https://dev59.com/JW855IYBdhLWcg3woV4_ - Damian Leszczyński - Vash
1
你应该首先决定是否要强制调用者处理异常。如果调用者无法执行任何有用的操作并且应该终止程序,则扩展RuntimeException或可能是Error。 - Peter Lawrey
@Vash,这是一个关于“在我的特定情况下什么样的面向对象设计更好”的问题,而不是关于“何时应该使用它们”的问题。请阅读实质而非标题。 - Denys S.
但是根据你的问题,很难说比Vash说得更多。这完全取决于你如何处理异常。有时候你可能需要捕获RuntimeException。有两个重要的区别:1. 你必须声明或检查已检查的异常,以确保你不会忘记它,2. 你不能通过外部方法传递自己的已检查异常(除非是已声明的子类)。就是这样。 - maaartinus
3个回答

9

我认为这完全合理。 RuntimeException 是一种很好的异常基类,用于表示调用代码不应该“处理”的异常 - 也就是当它们指示了一种可能意味着整个应用程序或者(对于服务器)请求应该被放弃的故障类型时。


这更像是一个“错误”(Error)。另一方面,RuntimeException是可以完全处理的,但有时候不太合理。NumberFormatException是一个很好的例子 - 如果你的字符串只匹配了"\d{1,3}",那么你就知道不会有任何NumberFormatException,所以没有必要处理它。在这种情况下,它更像是一个assert,如果正则表达式匹配代码中有一个bug,那么它将非常有用。但如果你从某个地方获得了一个字符串,那么捕获它并正确处理就是完全可以的。 - Sergei Tachenov
@Sergey:我认为NumberFormatException是RuntimeException的不幸例子。我认为Error更加严重,通常与操作环境本身出现问题有关(如VM死亡等)。对我来说,这似乎不应该是一个“错误”。但这绝对是一个灰色地带。 - Jon Skeet
Integer.parse(s)s=""的区别和 1/xx=0的区别在哪里?两者都可能是编程错误,而且sx都可能来自用户。 - maaartinus
@maaartinus:一个区别是,在执行计算之前测试x是否为0非常容易。而尝试解析值是否有效则更难预测。 - Jon Skeet
@maartinus,Jon是对的。纯属巧合,我尝试创建了一个匹配int类型所有有效字符串表示的正则表达式。虽然成功了,但看起来令人恐惧。 - Sergei Tachenov
显示剩余2条评论

2
第一个没问题。有许多异常是RuntimeException的子类。这里有很多例子。

2

这里有几种不同的观点。

首先(经典观点)认为,在大多数情况下应该使用checked exceptions。在这种情况下,方法必须将此异常声明为其签名的一部分或捕获它。这种方法的优点是接口始终清晰,并且每个层都关心自己的异常。但是这种方法相当冗长。有时你的代码会变得更长,你必须写几个try/catch语句,而不是调用几个方法并写一个if语句。

另一种方法是仅使用运行时异常。这种哲学认为,你不必处理异常,因为你与异常无关。在这种情况下,所有异常都是运行时异常,并在一个中央模块中捕获和处理。例如Spring框架采用了这种方法。

因此,答案取决于你正在开发的内容。如果这是独立的库,请使用已定义良好的checked exceptions。如果是应用程序或应用程序框架,则可以像Spring一样使用运行时异常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接