9

编写自定义异常类的目的是什么,而大多数情况下它的作用是相同的。例如,NullPointerException

class NullPointerException extends RuntimeException {
      private static final long serialVersionUID = 5162710183389028792L;


      public NullPointerException() {
          super();
      }


      public NullPointerException(String s) {
          super(s);
      }
}

这是我见过和创建的大多数异常类的基本模板。

我能想到的一个目的是处理这些异常。但是这不能基于异常消息吗?大多数情况下,我们为每种异常类型编写单个处理代码。我知道这有“例外”。

但是还有什么更多的吗?这不是在重复自己,只有类名发生变化吗?

还有任何 JDK 异常类有比这更多的代码吗?

4

6 回答 6

9

我能想到几个原因:

  • 拥有多个异常类允许程序员在他们的catch子句中具体化,并且只捕获他们关心的异常并知道如何处理。
  • 异常类可以携带有关导致异常的错误的信息。例如,ArrayIndexOutOfBoundsException携带有问题的数组索引,SQL 异常往往携带特定于数据库的错误代码和消息。
  • 异常规范——列出异常——可用于在编译时检查正确性。
于 2013-03-19T06:52:43.977 回答
2

好吧,简单地说,如果你不需要特殊的异常类,你就不应该做一个。如果你这样做了,那么你就做一个。它真的没有魔法。

如果您正在创建一个库,那么您当然应该从使用该库的开发人员的角度考虑(即使只是您):您的库是否出于特定原因抛出异常以及库用户是否可能想要特别抓住这些,因为他们可以切实地对此做一些事情(仅仅记录是不够的,IMO)。

标准异常类的示例:方法的调用者可能希望转换IndexOutOfBoundsExceptionnull返回值,同时让其他异常正常传播。

如果您希望以默认方式处理自定义异常,请扩展正确的现有异常类,例如IOException. 然后,当您想在那里做一些特定的事情时,您可以捕获您的特定 IO 异常,但IOException可以在不需要特殊处理时像其他任何事情一样处理它(不能做任何有用的恢复)。

如果你有一个完全自定义的异常,它不应该被超类 catch 捕获,它总是应该有特定的 catch 块,那么你Exception直接扩展。

我认为很少需要扩展RuntimeException,因为如果它意味着要被捕获的异常应该是Exception子类,并且如果它是为了结束程序或只是生成日志输出,那么它应该被RuntimeException自定义消息字符串的默认实现所覆盖.

于 2013-03-19T07:39:50.333 回答
1

您需要让您的客户端代码知道代码的哪一部分发生了确切的异常。所以你需要让异常语义和区别于其他代码块。

这个怎么做:

  1. 定义新的异常类,所以类名告诉发生了什么
  2. 定义一个统一的/通用的异常类,它包含codemessage其他信息。罐头告诉你会发生code什么。

总而言之,做一些事情让你的异常有一些意义/语义,并让它的客户知道到底发生了什么。

于 2013-03-19T08:14:11.660 回答
1
  1. 我们将可以自由地在我们的 Exception 类中添加更多方法来帮助客户,例如 rootCauseOfException()、description()、solution()、suggestions() 等。可以参考以下链接:
    https ://stackoverflow.com/a /22698673

  2. 如果您的项目具有相互依赖的模块,那么您也可以在相同的依赖层次结构中维护异常层次结构,这样如果您在基础层捕获单个异常,则将捕获所有相互依赖的模块异常。

  3. 您还可以在发送到客户端之前屏蔽一些敏感数据,如 ip、端口等。如果不使用自定义异常,则某些敏感数据可能会泄露给 slient。

  4. 您可以提供自己的异常消息,客户端可以轻松理解,而不是有时可能难以理解的 java 异常消息。

于 2016-10-10T17:33:12.163 回答
0

基本上就是以不同的方式处理不同的异常。比如说,您可能希望对 ArrayIndexOutOfBoundsException 执行一些与 NumberFormatException 不同的操作。

或更清楚地

}catch (ArrayIndexOutOfBoundsException ex){
//operation 1
}catch (NumberFormatException ex){
//operation 2
}
于 2013-03-19T06:51:47.840 回答
0

主要目的是识别自定义/应用程序特定的错误。您还可以在那里提供一些其他方法。例如,我们有返回自定义消息的自定义异常,并且还从堆栈跟踪中提取原因和位置。

于 2013-03-19T06:53:36.757 回答