Java中最常用的运行时异常是什么?

46
作为一名希望完善编程技能的Java程序员,我经常遇到需要创建运行时异常的情况。我知道如果明智使用它们是一种好的实践。
个人而言,在我创建的软件中,NullPointerExceptionIllegalStateException是最常用的。你呢?
你通常使用哪些运行时异常?在什么情况下会使用它们?
6个回答

68

我从不抛出 NullPointerException。对我来说,它是代码中自然出现的一种情况,当出现问题需要开发人员查看时,就需要修复原因,这样就不会再次出现。

我使用 IllegalStateException 来表示对象配置不正确或调用顺序不正确。然而,我们都知道,理想情况下,一个对象应该确保它不能处于错误状态,也不能以错误的顺序调用它(创建构建器和结果对象...)。

当方法检测到其参数不正确时,我使用大量的 IllegalArgumentException。这是任何公共方法的职责,停止处理(以避免更难理解的间接错误)。此外,方法开始时的一些 if 语句具有文档目的(这个文档永远不会与代码分离,因为它就是代码 :-) )。

     public void myMethod(String message, Long id) {
       if (message == null) {
          throw new IllegalArgumentException("myMethod's message can't be null");
          // The message doesn't log the argument because we know its value, it is null.
       }
       if (id == null) {
          throw new IllegalArgumentException("myMethod's id can't be null");
          // This case is separated from the previous one for two reasons :
          // 1. to output a precise message
          // 2. to document clearly in the code the requirements
       }
       if (message.length()<12) {
          throw new IllegalArgumentException("myMethod's message is too small, was '" + message + "'");
          // here, we need to output the message itself, 
          // because it is a useful debug information.
       }
     }

我还使用特定的运行时异常来表示更高级别的异常情况。

例如,如果我的应用程序的模块无法启动,当另一个模块调用它时,我可能会抛出一个名为ModuleNotOperationalException的异常(理想情况下是由通用代码如拦截器抛出,否则由特定代码抛出)。在做出这种架构决策后,每个模块都必须处理在调用其他模块时引发的该异常...


8
很棒的列表;我会加上UnsupportedOperationException,因为我经常在特定的集合接口实现中使用它。 - Carl
好的回答。我将来会更加注意 IllegalStateException! - reef
1
很棒的回答。我只能+1一次,但我会做两次:一次是为了好的解释,一次是为了自我记录的前提条件执行。我经常使用assert来实现这些,但非法参数对于这种情况是完美的匹配。 - CPerkins

12

我一直认为运行时异常应该代表编程错误(例如,传递了不期望的null引用、数组索引越界等),而检查异常应该代表环境中无法“编码解决”的异常情况(例如,IOExceptionSQLException)。

这个规则有时会被破坏,因为有时你需要将本来应该是检查异常的内容包装在RuntimeException中,以满足接口定义。简单来说,你可能有一个漂亮的java.util.List实现,它可以在多台机器之间管理分布式列表。很明显,如果在其自身中定义,则会抛出检查异常(可能是IOException的某个子类)。但是让这个类实现List的好处是,客户端几乎可以在使用其他列表的任何地方透明地使用它。

然而,这样做可能会导致 Joel 所称的泄漏的抽象,因此重要的是确保您的文档清楚说明可能抛出哪些异常以及它们的含义!在这种情况下,我发现自定义RuntimeException子类通常更清晰地传达根本原因,而不是试图将其塞入现有的运行时异常类中。


你在Java的原始思想中与CheckedExceptions保持一致。实际上,这被认为是Java唯一的原创特性(其他所有特性都来自于其他成功的编程语言)。但是关于这个问题已经有了很多争论,我认为当前的趋势是将这种区别视为Java中的错误。具体的问题超出了此处的讨论范围,你可以通过谷歌搜索来了解它们... - KLE

3

我经常使用 IllegalArgumentException。大多数情况下,我会尽快返回默认值,但有时不行,所以我会使用这个。

另一个我使用的是 ArrayIndexOutOfBoundsException


3

未知异常,非常有用:P

我也喜欢org.apache.commons.lang.NotImplementedException


15
我使用throw new UnsupportedOperationException("Not yet implemented");来标记我应用程序中尚未完成的部分。 - Jesper

3

根据Joshua Bloch在《Effective Java》中的说法,最常被重用的异常包括:

  1. IllegalArgumentException(非法参数异常)
  2. IllegalStateException(非法状态异常)
  3. NullPointerException(空指针异常)
  4. IndexOutOfBoundsException(索引越界异常)
  5. ConcurrentModificationException(并发修改异常)
  6. UnsupportedOperationException(不支持操作异常)

2

我通常不会抛出运行时异常,而是在检查特定条件后抛出自定义异常。但我使用过的几个运行时异常包括 - IllegalAccessException(非法访问异常)、ArithmeticException(算术异常)、NumberFormatException(数字格式异常)和SecurityException(安全异常)。


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