当我创建一个新的Exception时,我必须抛弃它,还是可以将它放在List中?

时间:2011-04-04 10:21:03

标签: java exception-handling

我有一个项目,我必须解析格式化的ASCII数据。解析器有可能识别格式化中的问题(预期未找到,发现意外数据)。通常,如果我发现某些事情失败,我会抛出异常。但是,这一次,我想继续解析过程,并将解析器错误存储在结束类中。我的问题是,是否可以创建一个新的Exception并将其存储在一个List而不是抛出它以免停止处理?

4 个答案:

答案 0 :(得分:6)

  

我的问题是,是否可以创建一个新的Exception并将其存储在一个List而不是抛出它以免停止处理?

是。那可行。但它相当昂贵,因为Exception对象捕获所有当前线程的堆栈帧。如果你不打算使用堆栈帧而不是抛出异常,那么你已经做了很多不必要的工作。除非有必须使用Exception的特定原因,否则一个简单的类来捕获错误详细信息是一个更好的主意。

但是,有一个聪明的黑客/技巧可以用来使实例化的异常对象更便宜。如果您查看Throwable API,您会注意到有一个名为fillInStackTrace()的方法。该方法由Throwable构造函数本身调用以捕获堆栈帧,并且实现(在Throwable中)在一些本机代码中执行此操作。但是,此方法不是final,因此您可以在自定义异常类中覆盖它以将其转换为无操作。

瞧!一个运行速度更快的构造函数!但是,当然,如果你需要一个异常的堆栈跟踪,那你就不走运了。所以我建议非常谨慎地使用这个黑客/技巧。

答案 1 :(得分:3)

如果您不想中止处理(即您可以在本地处理问题),则不应使用例外。创建一个异常但不抛出异常并不是一个好主意(它相当昂贵,并且它不是“主流”,所以它使你的代码更难理解和使用)。

最好只创建例如错误消息字符串并将其存储在问题列表中。或者,如果您需要存储更多结构化错误信息,请为其创建自定义类。

答案 2 :(得分:3)

您可以执行以下操作:

  • 存储List个问题(例如,字符串消息列表或包含问题详细信息的特定对象列表)
  • 最后,如果列表不为空,则抛出包含列表的自定义异常

例如:

List<ParsingProblem> problems = new ArrayList<ParsingProblem>();
while (parsing) {
  ...
  problems.add(new ParsingProblem("some message", someRelevantValue));
}

if (!problems.isEmpty()) {
   throw new ParsingException(problems);
}

答案 3 :(得分:2)

语言或JVM规范中的任何内容都不会强制您抛出Exception,您可以像处理Java中的任何其他Object一样处理它。所以是的,从这个方面来看,保留Exception个对象的列表是完全可以的。

然而,这是一件相当不寻常的事情。我不会把它称之为糟糕的设计本身,但它有点奇怪的气味。

也许您可以通过创建Problem并将其保留在List(并在自定义Exception中添加此类对象)来避免此问题。