java - 是否有收集异常的标准方法?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (47)

我有一个解析几个不同的输入文件的Java程序。即使在此输入文件中发现错误,解析仍然可能会继续并收集其他几个错误。所以我想要做的不是抛出和异常,并停止解析过程,我想注册异常到某个地方,然后继续解析并以类似的方式收集其他几个错误,然后最后我想检查是否会报告任何错误,并根据此情况失败或继续。

当然,我总是可以通过编写ExceptionRegister或任何类来手动执行此操作,但我想知道两件事情:

1)这种方法有问题吗?你知道我想做什么的其他设计吗?

2)有没有这样做的标准方式?(例如,而不是滚动我自己的类,如果可能,我想使用内置功能)

我不知道为什么,但有人在我接受他的答案之前刚刚删除了他的答案。无论如何,我认为简单的数据结构应该起作用。基本上,我会编写一个收集多个错误消息的异常类。然后我会调用它的抛出方法,如果它至少有一条错误信息被注册,它就会抛出。

这里有更多的说明。我的问题与解析无关。解析只是一个例子,因为我的程序做了一些解析。想一想:我正在运行一种算法,如果出现错误,我可以继续使用算法来收集更多错误,以便不打印出一个错误,并且在修复错误时打印第二个错误,我可以一起打印这两个错误。

提问于
用户回答回答于

当你无法处理输入时,应该真的使用异常。他们是你的代码中说的特殊情况:“我放弃了,我错过了一些信息,或者我不是为了这个”。这是如何定义这种情况的灰色地带,但文章中提出的通常理念是:

避免使用例外来指示可合理预期的条件,作为该方法典型功能的一部分。

就你而言,这听起来像你必须解析的内容可能是不正确的,但这是你的程序所期望的,并没有足够的破坏合约来停止解析。另一方面,例如,如果输入语法中的错误导致解释的其余部分失败,则可接受的异常将是有效的。

但是人们仍然使用异常,因为它们非常方便停止执行,并且不需要通过返回结果的繁琐细节就可以进入堆栈。但是在它的副本中,当你在某些对象中留下一些无人值守的状态时,它们可能会有棘手的结果。

您的需求听起来更像是需要验证模式,而不是一个可能导致处理停止的异常。停止所有处理的一个例外是:如果您抛出一个,其余的将被忽略。但你建议你收集它们而不是扔这些。所以我会说,在那种情况下,为什么要使用例外呢?看来你确实想要返回正确的结果,而不是停止程序的执行。

因为如果你仍然沿着这条路走下去,你可能会收集一些例外情况。你扔哪一个?在您创建的例外收集器中,哪一个优先?

以Eclipse为例,它有这个庞大的收集插件贡献巨大的平台。他们使用适当的通信渠道来记录任何警告和错误,无论是在问题窗格还是通过执行后台任务。后者的执行通常会返回一个IStatus对象或一个变体。基于此IStatus对象,接收状态的代码决定对其执行操作。

因此,我个人开发了一个类似的对象,它可以收集所有必要的用户错误(而不是程序的错误),不会中断程序的执行和合同的可接受部分。该对象可以包含错误的严重程度,其来源,以及如何解决该错误的提示(这可以是一个字符串,甚至包含用于显示错误的指示逻辑或可能是部分自动修复的方法)等。一旦执行完成,解析结果将得到这些状态对象并对其执行操作。如果有错误,请通过用户界面通知用户并记录。

因此,它基本上与最初建议的方法相同,即减去例外并减去跳过堆栈的商品,这可能导致令人讨厌的副作用,并且很难调试错误。

用户回答回答于

我想我现在明白了。你实际上试图做的是收集解析错误(你表示为例外)并继续解析当前输入文件。

没有标准的方法来做到这一点:

“异常寄存器”实际上只不过是解析错误描述符列表......大概是一些解析器异常。如果您可以在适当的位置捕捉​​到异常,将它添加到“注册”中并不重要。

困难的部分是你没有谈论的功能:

  • 如何捕获错误的位置
  • 如何让解析器在解析器错误时继续解析。

这些解决方案取决于您如何实现解析器。

  • 如果您使用的是解析器生成器,那么PGS文档很有可能解释了如何实现这一点。
  • 如果您正在手动实现解析器,则需要滚动自己的代码来跟踪错误位置并执行语法错误恢复。

基本上,我会编写一个收集多个错误消息的异常类。然后我会调用它的抛出方法,如果它至少有一条错误信息被注册,它就会抛出。

这听起来像是滥用例外。更好的办法是将错误累积到列表中,然后在列表非空时创建/抛出异常。如果您想避免重复代码,请在助手类中使用静态方法。

(IMO)有条不紊地抛出异常!并且创造很多你不太可能抛出的例外可能是低效的。(根据JVM的不同,昂贵的异常部分通常会创建异常并捕获堆栈帧,但费用可能很高。)

扫码关注云+社区