抛出异常和抛出特定异常(例如NullPointerException)之间的区别

时间:2016-07-12 14:51:21

标签: exception exception-handling language-agnostic throws

我想知道抛出Exception和抛出NullPointer Exception之类的特定异常之间有什么区别。

据我所知,Exception应该能够捕获任何类型的异常,因为使用特定的Exception期望只能抛出该异常类型。

示例:

void test(String testString) throws Exception;

VS

void test(String testString) throws NullPointerException;

如果这对我来说是正确的,那么总是抛出异常并永远不会命名特定的异常是有意义的。我错过了一些重要的东西吗?它至少会影响性能吗?很多人都在寻找抛出和捕捉异常,但没有人问这个非常基本的问题。

除了Exception之外,我没有看到抛出任何异常的好处。

4 个答案:

答案 0 :(得分:4)

至少有两个原因可以让您想要抛出特定类型的异常:

  1. 如果程序因异常而失败,您将获得更多信息以确定哪里出错。将ExceptionFileNotFoundException进行比较。后者显然为您提供了更多信息。
  2. 在某些情况下,代码会想要捕获某些类型的异常。例如,在使用串行端口时,您可能希望以TimeoutException的方式捕获和处理NullReferenceException

答案 1 :(得分:3)

首先,Exception是每个Exception的基本类型。就像object就是一切。

通过抛出特定的Exception,您可以向消费者提供有关已发生事件的更多信息。 想象一下,在没有消息的情况下获得普通Exception,消费者丢失的情况。例如,当框架抛出NullReferenceException时,您就会意识到您的某个对象没有它试图访问的引用。

这就是你如何链接异常并使用它们的类型:

try
{
   throw new NotImplementedException();
}
catch(NullReferenceException ex)
{
   // Logic for NullReference exception if needed.
}
catch(NotImplementedException ex)
{
   // This will be executed.
}
catch(Exception ex)
{
   // Will catch every exception.
}

答案 2 :(得分:2)

您提到的NullPointerException是常规Exception的一个非常好的示例,因为它是RuntimeException的子类。 <{1}}的(子类)的任何抛出都不必被捕获或声明。

任何其他(=不是RuntimeException的子类)必须通过try / catch块或RuntimeException声明在代码中处理异常。否则,你的代码甚至不会编译!这迫使您作为开发人员处理可能弹出的错误。

至于为什么使用不同的Exception类型很有用,请考虑以下使用多个throws语句的简单示例:

catch

在这个例子中,两个不同的异常以两个不同的catch块结束,这使得您可以以不同的方式处理这些错误。

答案 3 :(得分:0)

抛出特定异常而不是通用异常是最佳做法。这是因为调用者可能希望以不同方式处理异常,例如在WebApi中,您可能希望为ArgumentNullException返回错误请求响应(400),但您可能希望为其他类型的异常返回不同的结果。例如,您可能实际抛出自定义NotFoundException,然后控制器将捕获它并返回Not Found响应(404)。 基本上,如果您抛出特定的异常,则允许使用者代码以他们想要的方式处理不同的异常情况。