如果捕获空指针exception不是一个好习惯,捕获exception是一个好的吗?

我听说捕获NullPointerException是一种不好的做法,我认为这是明智的。 让NullPointerException传播到顶部将允许检测出错的东西。 但很多时候我看到很多朋友直接捕获Exception ,因此他们不必担心上面代码中可能出现的所有不同类型的exception。 这是一个好习惯吗? 什么是最好的未处理的其他类型的例外? 除此之外,我还可以在特定代码上处理NullPointerException ,我们确定exception的来源。 那么何时处理exception以及什么时候不应该处理它们? 什么是可能的最好的例外列表,最好不做处理?

口袋妖怪exception处理很糟糕。 特别是,如果它是一个空块而你只是吞咽它们。 你有特定类型的exception,因为它们实际上是指特定情境中的特定事物(实际上它们告诉你出了什么问题)。 因此,通过捕获Exception你会说你不关心这些exception是什么,你不关心发生了什么。 这可能不是你想要的。

通常,捕获exception时遵循以下规则:

  • 在这个级别处理exception是否有意义? 如果是,那就处理它。 如果没有,那么传播。
  • 结合第一条规则,“处理”也可以意味着,捕捉,包裹和重新投掷。 这是一种防止抽象泄漏的方法,因此您的方法的调用者不必了解底层实现。
  • 空catch块并不意味着您已经处理了exception。 那被称为“吞咽”; 至少,您要记录exception。 有时发生exception实际上是代码逻辑流程的一部分,因此您可能希望做一些特殊的事情(但是,请原谅双关语,例外而不是规则。最好检查导致exception的情况而不是将它们合并到代码的逻辑流程中)。

您可以在代码中轻松检查空值,因此无需显式捕获空指针exception。 让NullPointerException发生是没有意义的(这是不好的做法)。 即使您有一些抛出NullPointerException代码,并且它是您无法控制且无法修复的代码,您应该确定导致NullPointerException并专门测试它们的输入参数。

您不应该捕获的另一个例外是IllegalArgumentException 。 这个exception意味着你传递了一个没有意义的参数。 您应该显式测试输入参数以确保它们是正确的,并且它们不会导致IllegalArgumentException ,而不是捕获此exception。

捕获NullPointerException的“原因”被认为是一种不好的做法并不是因为当出现问题时你应该让它冒出来! 说任何例外是“最好不要处理”仅基于其类型似乎是一个坏主意。

NPE被认为是编程错误的结果。 严格正确的程序永远不应该生成一个。 看到它被捕获的原因很糟糕,它通常意味着代码扔了一个,程序员决定抓住它并掩盖它,而不是修复导致它的破坏代码!

例如,如果您出于业务原因将其耦合到内部存在错误并且偶尔会抛出空指针的API,那么抓住它,做一些事情/通过更好的消息通知用户将是完全合法的。 让’null’点击UI只是因为有人说“捕捉空指针exception是坏的”是没有意义的!

在特定情况下捕获java.lang.Exception可能是合法的,但通常“我很懒”不是其中之一。 :)例如,如果您正在实现一个API并且想要确保没有任何exception从规范中出现,那么您可能会捕获Exception并将其包装在您定义的某个应用程序exception中。

如果可以通过这样做添加一些值,则应该只捕获exception。 否则你应该让它传递给调用者。

NullPointerException通常是代码中的错误的结果。 你怎么能明智地把它固定在一个挡块上?

没有被关于例外的困扰并不是一种好的做法。

通常,您应该捕获exception的唯一时间是您是否可以以某种有意义的方式处理它。 如果你不能,你应该简单地让它冒泡到顶部并终止进程。 例如,您是否可以从NullPointerException或I / O错误中以某种有意义的方式恢复? 我想不是。

我的exception处理规则:

  • 通常,不要捕获exception,除非您能以某种有意义的方式处理它们。
  • 捕获进程/机器边界的exception,记录捕获的exception以及可用的任何上下文并重新抛出它。 如果exception是自定义exception,则可以将其包装在调用进程已知/有用的类型的exception中并抛出该exception。
  • 您还可以在较低级别捕获exception,其中您拥有最多的运行时上下文,记录exception和关联的上下文,然后重新抛出exception。
  • 当重新抛出时,使用throw ; 而不是throw caughtException ; 。 使用前一种语法可保留原始堆栈跟踪; 使用后一种语法会创建一个新的堆栈跟踪,以throw caughtException ; – 丢失所有上下文并调用堆栈直到捕获到exception的位置。
  • 如果您这样选择,您可以在较高级别捕获exception并优雅地终止该过程,记录exception信息以帮助调试和纠正基础问题。

不要将exception用作流控制机制(如果可能)。 例外情况本质上应该是特殊的。 相反,premptively,为您调用的任何方法强制执行调用者的合同结束(前提条件)。

参见Bertrand Meyers的书, 面向对象的软件构建,第2版。 了解更多信息。

捕获exception的主要规则是你必须知道为什么要这样做。 当程序员想要进行一般error handling并且他并不真正关心究竟发生了什么时,就会遇到exception类,主要的是出了问题。 在这种情况下,他可能决定回滚交易或进行一些清理。 如果您正在捕获特定exception,请尝试应用相同的规则。 我知道你为什么这么做,那就是这样做的。 但是,如果有人想要在NPE的情况下做一些非常特别的事情,这种情况非常罕见。

如果你有一个优雅的方式来处理你的exception,那么抓住它是有用的,如果不希望调用者有一个很好的方法来处理它。