当前位置: 首页 > 面试题库 >

异常传播准则(Java)

汪甫
2023-03-14
问题内容

是否有关于Java中异常传播的准则?

何时在方法签名中添加例外?例如:如果仅当缺少必要的程序资源时才引发异常,并且只能在顶层进行处理,那么是否可以将所有使用erring方法的方法传播给使用此异常的所有方法?

有没有好的做法?有不良做法吗?

很抱歉,如果我含糊不清,但是我只是在寻求有关异常的编程风格的(一般)建议。


问题答案:

过去对我有帮助的准则包括:

  • 当方法无法处理异常时引发异常 ,更重要的是,应由调用方处理。一个很好的例子出现在Servlet API中-在某些无法正确读取请求的情况下,doGet()和doPost()抛出ServletException或IOException。这两种方法均不能处理异常,但是容器是(在大多数情况下,导致50x错误页面)。
  • 如果方法无法处理,则将异常冒泡 。这是上面的推论,但适用于必须捕获异常的方法。如果捕获的异常无法通过该方法正确处理,则最好对其进行冒泡。
  • 立即抛出异常 。这听起来可能含糊不清,但是如果遇到异常情况,那么最好抛出一个异常以指示原始故障点,而不是尝试通过错误代码来处理故障,直到认为适合抛出异常的点为止。换句话说,尝试最小化混合错误处理和错误处理。
  • 记录异常或冒泡,但不要同时执行 。记录异常通常表明异常堆栈已完全解开,这表明没有发生任何进一步的异常冒泡。因此,不建议同时执行这两项操作,因为这通常会导致令人沮丧的调试体验。
  • 当您除调用方之外的其他人来处理exception时, 请使用java.lang.Exception(检查的异常)的子类。如果调用者不处理异常,这将导致编译器抛出错误消息。请注意,这通常会导致开发人员“吞噬”代码中的异常。
  • 使用 java.lang.RuntimeException的子类(未经检查的异常)来指示编程错误。这里推荐的异常类包括IllegalStateException,IllegalArgumentException,UnsupportedOperationException等。同样,必须谨慎使用NullPointerException之类的异常类(几乎总是抛出该异常的做法)。
  • 使用异常类层次结构在各个层之间传递有关异常的信息 。通过实现层次结构,您可以概括调用者中的异常处理行为。例如,您可以使用像DomainException这样的根异常,该异常具有多个子类,例如InvalidCustomerException,InvalidProductException等。这里的警告是,如果将每个单独的例外情况表示为单独的异常,则异常层次结构可能会迅速爆炸。
  • 避免捕获无法处理的异常 。很明显,但是很多开发人员试图捕获java.lang.Exception或java.lang.Throwable。由于可以捕获所有子类化的异常,因此,当捕获“全局”异常类时,应用程序的运行时行为通常很模糊。毕竟,人们不想捕获OutOfMemoryError-应该如何处理这样的异常?
  • 小心包装例外 。重新抛出异常会重置异常堆栈。除非原始原因已提供给新的异常对象,否则它将永远丢失。为了保留异常堆栈,必须将原始异常对象提供给新异常的构造函数。
  • 仅在需要时才将已检查的异常转换为未检查的异常 。当包装一个异常时,可以包装一个检查的异常并抛出一个未检查的异常。在某些情况下,这很有用,尤其是在打算中止当前正在执行的线程时。但是,在其他情况下,这可能会造成一些麻烦,因为不执行编译器检查。因此,将已检查的异常调整为未检查的异常并不意味着会盲目地进行。


 类似资料:
  • 当异常被抛出到组播中时,Camel不会传播异常。 在以下设置下,从其beanref引发异常: 为什么我不能向父路由提出多播异常? 骆驼2.17-快照

  • 问题内容: 什么是异常传播?我尝试使用Google,但找不到满意的结果。最好用Java来解释这一点。 问题答案: 令人惊讶的是,在Java教程页面中有关exception的解释。 异常从一个方法传播到另一个方法,直到调用被捕获为止。因此,如果调用,调用,调用,并且如果抛出异常,则除非这些方法之一捕获到该异常,否则该异常将从d传播到c到b传播到a。

  • 问题内容: 我是C程序员,最近刚学习一些Java,因为我正在开发一个Android应用程序。目前,我处于一种情况。以下是一个。 现在,我希望在另一个类的其他地方使用方法MyMethod()的调用。如果有人可以为我提供一些代码片段,如何将异常传播到MyMethod()的调用者,以便可以在调用者方法的对话框中显示它们。 对不起,如果我对这个问题的回答不太清楚和奇怪。 问题答案: 只是首先不要捕获异常,

  • 问题内容: 我很快就遇到了这种愚蠢的行为,在这种行为中,强制展开可选对象不会传播。 从文档中: 尝试使用!访问不存在的可选值会触发运行时错误。在使用!之前,请始终确保可选内容包含非nil值。强制释放其价值。 复制: 和 这对我来说似乎不合逻辑或前后不一,我找不到有关此主题的任何文档。 这是设计使然吗? 问题答案: 从文档中: 错误处理 错误处理是响应程序错误状态并从错误状态中恢复的过程。Swift

  • 我正在阅读Scala 2.11.8留档的函数在scala.concurrent.Future模块,它说: 将副作用函数应用于这个未来的结果,并返回一个包含这个未来的结果的新的未来。 这个方法允许强制回调以指定的顺序执行。 请注意,如果其中一个链式第四个回调引发异常,则该异常不会传播到后续的第四个调用。相反,随后的第四次回调将被赋予此未来的原始值。 我不确定< code >和不传播异常到底是什么意思

  • 问题内容: 我有一个流程,在CXF客户端上我安装了拦截器,提供程序和异常映射程序。就我而言,我正在通过拦截器捕获来自客户端的不良响应,然后我想中止cxf总线链并引发故障。不幸的是我做不到,因为在每种情况下都只记录从拦截器抛出的异常,但是主要错误(错误的json格式)会传播到异常映射器。我想避免使用异常映射器,但是我不知道怎么做。我正在使用WebClient来实现这样的拦截器: 我读到我应该实现ja