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