2011-04-04 32 views
1

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

回答

3

你可以做到以下几点:

  • 店的问题List(字符串的邮件列表,例如,或者包含问题细节的特定对象的列表)到底
  • ,如果列表不为空,抛出具有列表

例如自定义异常:

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

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

我不会使用这个类的名称错误。 (原因,从你的构造函数来看,我假设你不是指'java.lang.Error')。 – aioobe 2011-04-04 10:29:20

+0

@aioobe yesh,它不是java.lang.Error。我会选择另一个名字。实际上,我已经看到这种情况下的类确实被称为'错误',但也许不太合适。 – Bozho 2011-04-04 10:31:21

+0

这是一个相当明确的方式,我相信。坦率地说,我自己应该想到这个,但由于某种原因,我的头因为例外而停滞不前。 – JRSofty 2011-04-04 12:29:59

3

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

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

6

我的问题是,可以创建一个新的异常,只是将它存储在一个列表中,而不是抛出它不停止处理?

是的。那可行。但是,这是相当昂贵的,因为Exception对象捕获当前线程的所有堆栈帧。如果你不打算使用堆栈框架并且不打算抛出异常,那么你做了很多不必要的工作。除非有一个特定的原因,你需要必须使用Exception,那么捕捉错误细节的简单类是一个更好的主意。

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

瞧!构造函数运行速度更快!但是,当然,如果你需要一个堆栈跟踪来处理异常情况,那么你运气不好。所以我建议非常谨慎地使用这个黑客技巧。

+1

您可以覆盖'fillInStackTrace()'以避免总是支付这笔费用。我不确定'Throwable'的构造函数是否调用'fillInStackTrace()'。 – jmg 2011-04-04 10:32:15

+0

@jmg ...我到了那里。 – 2011-04-04 10:35:37

+0

@Stephen C:当'fillInStackTrace()'被覆盖时,你并不一定缺乏。可以使用'super.fillInStackTrace()'从'public void reallyFillInStackTrace(){super.fillInStackTrace(); }'。 – jmg 2011-04-04 10:37:57

2

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

但是,这是一件很不寻常的事情。我本不会把它称为一个糟糕的设计,但它有点奇怪的气味。

也许你能避免这个问题,通过创建一个Problem,并保持在一个List(和您的自定义Exception添加这样的对象)。

相关问题