我有一个项目,我必须解析格式化的ASCII数据。解析器可能会识别何时出现格式问题(预计未找到,发现意外数据)。通常情况下,如果我发现一些失败,我会抛出异常。但是,这一次,我想继续解析过程,并将解析器错误存储在结束类中。我的问题是,创建一个新的异常并将其存储在List中而不是抛出它以便不停止处理可以吗?当我创建一个新的异常时,我必须抛出它还是可以将它放入List中?
回答
你可以做到以下几点:
- 店的问题
List
(字符串的邮件列表,例如,或者包含问题细节的特定对象的列表)到底 - ,如果列表不为空,抛出具有列表
例如自定义异常:
List<ParsingProblem> problems = new ArrayList<ParsingProblem>();
while (parsing) {
...
problems.add(new ParsingProblem("some message", someRelevantValue));
}
if (!problems.isEmpty()) {
throw new ParsingException(problems);
}
如果您不想中止处理(即您可以在本地处理问题),则不应使用异常。创建一个异常,但不抛出它是不是一个好主意(它是相当昂贵的,它不是“主流”,所以它使你的代码更难理解和使用)。
最好是创建例如一个错误消息字符串并将其存储在问题列表中。或者,如果您需要存储更多结构化的错误信息,请为其创建一个自定义类。
我的问题是,可以创建一个新的异常,只是将它存储在一个列表中,而不是抛出它不停止处理?
是的。那可行。但是,这是相当昂贵的,因为Exception对象捕获当前线程的所有堆栈帧。如果你不打算使用堆栈框架并且不打算抛出异常,那么你做了很多不必要的工作。除非有一个特定的原因,你需要必须使用Exception
,那么捕捉错误细节的简单类是一个更好的主意。
但是,您可以使用巧妙的技巧/技巧使实例化的异常对象更便宜。如果您查看Throwable
API,您会注意到有一种方法称为fillInStackTrace()
。该方法由Throwable
构造函数本身调用来捕获堆栈帧,并且实现(在Throwable
中)在某些本机代码中执行此操作。但是,此方法不是final
,因此您可以在自定义异常类中重写它以将其变为无操作。
瞧!构造函数运行速度更快!但是,当然,如果你需要一个堆栈跟踪来处理异常情况,那么你运气不好。所以我建议非常谨慎地使用这个黑客技巧。
您可以覆盖'fillInStackTrace()'以避免总是支付这笔费用。我不确定'Throwable'的构造函数是否调用'fillInStackTrace()'。 – jmg 2011-04-04 10:32:15
@jmg ...我到了那里。 – 2011-04-04 10:35:37
@Stephen C:当'fillInStackTrace()'被覆盖时,你并不一定缺乏。可以使用'super.fillInStackTrace()'从'public void reallyFillInStackTrace(){super.fillInStackTrace(); }'。 – jmg 2011-04-04 10:37:57
语言或JVM规范中的任何内容都不会强制您抛出Exception
,您可以像处理Java中的其他任何Object
一样处理它。所以是的,从这方面来说,保留一个Exception
对象的列表是完全正确的。
但是,这是一件很不寻常的事情。我本不会把它称为一个糟糕的设计,但它有点奇怪的气味。
也许你能避免这个问题,通过创建一个Problem
,并保持在一个List
(和您的自定义Exception
添加这样的对象)。
- 1. 抛出一个异常,为什么它必须是静态的?
- 2. 我可以使用Moodle'API'吗?还是我必须刮它
- 3. 每当我将它放入htaccess中时,是否必须放置“RewriteEngine”?
- 4. 如何创建一个新的异常类并抛出它
- 5. 如果我的父类抛出一个异常,我的子类是否必须捕获它?
- 6. Clojure抛出一个异常,当我不期望它
- 7. shoppingcart新手。我必须购买还是可以建立
- 8. 我可以在不抛出它的情况下实例化一个异常吗?
- 9. 我们可以忽略屏幕方向吗?还是我们必须处理它?
- 10. 我的代码请求异常被抛出,但是当我做,它说,它不应该被抛出
- 11. 它说:“一个地址必须指定”当我有它
- 12. Info.plist关键字符串 - 在SDK中定义,还是我必须创建它们?
- 13. 抛出的异常:你必须调用removeView上的fragment创建
- 14. 我的程序抛出一个异常,但它运行良好
- 15. 当我不知道它可能抛出的位置时,如何记录异常?
- 16. Bootstrap CSS和JS我必须将它们包含在单独的文件中还是可以编译它们?
- 17. 我可以使用getElementByID('oct_6_2013')当它涉及到一个DOMDocument-> saveHTML或它必须是一个DOMDocument-> loadHTML
- 18. 抛出一个异常,捕获它
- 19. 转换为List()抛出异常对象必须实现IConvertible
- 20. 当我创建一个新的字符时,std :: bad_alloc被抛出**
- 21. Android DialogFragment:我可以重新使用,还是必须重新使用另一个?
- 22. StructureMap认为它必须注入构造函数并抛出异常
- 23. 抛出一个新的异常抛出一个旧的异常
- 24. QBXML:我可以得到资产负债表还是必须计算它?
- 25. 我可以从_CrtSetReportHook抛出异常吗?
- 26. 创建c#异常而不是抛出它
- 27. 为什么我们必须处理不抛出异常的方法的异常?
- 28. 我是否必须创建一个新的数据库?
- 29. 抛出异常后我必须打破吗?
- 30. 抛出异常:封装它们还是不封装?
我不会使用这个类的名称错误。 (原因,从你的构造函数来看,我假设你不是指'java.lang.Error')。 – aioobe 2011-04-04 10:29:20
@aioobe yesh,它不是java.lang.Error。我会选择另一个名字。实际上,我已经看到这种情况下的类确实被称为'错误',但也许不太合适。 – Bozho 2011-04-04 10:31:21
这是一个相当明确的方式,我相信。坦率地说,我自己应该想到这个,但由于某种原因,我的头因为例外而停滞不前。 – JRSofty 2011-04-04 12:29:59