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

java—是否有收集异常的标准方法?,java,exception,exception-handling,Java,Exception,Exception Handling,我有一个Java程序,可以解析几个不同的输入文件。即使在该输入文件中发现错误,解析仍然可以继续并收集其他几个错误。所以我想做的不是抛出异常并停止解析过程,而是将异常注册到某个地方,然后继续解析并以类似的方式收集其他几个错误,最后我想检查是否报告了任何错误,并根据这一点失败或继续 当然,我可以通过编写ExceptionRegister或任何类来手动完成这项工作,但我想知道两件事: 1) 这种方法有问题吗?你知道我想做什么的替代设计吗 2) 有没有一个标准的方法可以做到这一点?(例如,如果可能的话,

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

当然,我可以通过编写ExceptionRegister或任何类来手动完成这项工作,但我想知道两件事:

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

2) 有没有一个标准的方法可以做到这一点?(例如,如果可能的话,我希望使用内置功能,而不是滚动我自己的类)

谢谢

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


编辑2:这里有更多的澄清。我的问题与解析无关。解析只是一个例子,因为我的程序进行了一些解析。想一想:我正在运行一个算法,如果出现错误,我可以继续执行该算法以收集更多错误,这样,我就可以不打印一个错误,而在修复错误后打印第二个错误,而是将这两个错误一起打印。

我想我现在明白了。实际上,您要做的是收集解析错误(将其表示为异常)并继续解析当前输入文件

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

“异常寄存器”实际上只是一个解析错误描述符列表。。。可能是一些解析器异常。如果您可以在适当的点捕获异常,那么将其添加到“寄存器”中就很简单了

困难的部分是您没有提到的功能:

  • 如何捕获错误的位置

  • 当解析器出现错误时,如何让解析器继续解析

这些问题的解决方案取决于您如何实现解析器

  • 如果您使用的是解析器生成器,那么PGS文档很可能会解释如何实现这一点

  • 如果您是手工实现解析器,则需要滚动自己的代码来跟踪错误位置并执行语法错误恢复


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

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


有条件地抛出自己的异常(依我看)很奇怪!创建大量不太可能抛出的异常可能是低效的。(根据JVM的不同,异常的昂贵部分通常是创建异常和捕获堆栈帧。花费可能很大。)

当您无法处理输入时,应该真正使用异常。它们是一种特殊情况,在这种情况下,您的代码会说“我放弃了,我丢失了一些信息,或者我不适合这样做”。这是一个关于如何定义此类案例的灰色地带,但比尔·维纳斯(Bill Venners)在书中提出的通常理念是:

避免使用例外情况来指示可以合理使用的条件 作为该方法典型功能的一部分

在您的情况下,听起来您必须解析的内容可能不正确,但这是您的程序所期望的,并且没有破坏足够的契约来停止解析。另一方面,例如,如果输入语法中的错误导致其余解释失败,则可以使用可接受的异常

但是人们仍然使用exception,因为它可以非常方便地停止执行并提升堆栈,而不必涉及到结果返回的繁琐细节。但在它的对应对象上,当您在某些对象中留下一些无人参与的状态时,它们可能会产生棘手的结果

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

因为如果你仍然沿着这条路走,你可能会在最后抛出一组异常。你扔哪一个?在您创建的异常收集器中,哪一个优先

以Eclipse为例,它有一个巨大的平台来处理大量的集合插件贡献。他们使用适当的通信通道将任何警告和错误记录在问题窗格或日志中。后者的执行通常会返回一个或一个变量。基于此
IStatus
对象,接收状态的代码决定对其进行操作

因此,就我个人而言,我会开发一个类似的对象来收集所有必要的用户错误(而不是程序错误),它不会破坏程序的执行和合同的可接受部分。此对象可以包含错误的严重性、错误源、如何修复错误的提示(可以是字符串,甚至可以是包含用于显示er的精确定位逻辑的方法)