IllegalStateException 可以用来捕获所有子异常吗?
我想知道在这种情况下使用 IllegalStateException 对于 API 来说是否是一个很好的设计选择。
场景: 我有一个函数可以检查 XML 文档是否格式良好,并具有以下签名:
public boolean isXMLDocumentWellFormed(InputStream inXMLDocument)
该函数使用以下代码片段来加载 XML 文档:
boolean isXMLDocWellFormed = false;
// Setup document builder
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
.newInstance();
if (docBuilderFactory == null)
throw new IllegalStateException(
"The DocumentBuilderFactory cannot be instanciated");
try {
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
// Parse document
Document doc = docBuilder.parse(inXMLDocument);
if (doc != null)
isXMLDocWellFormed = true;
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new IllegalStateException(e);
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new IllegalStateException(e);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new IllegalStateException(e);
}
return isXMLDocWellFormed;
API 的设计非常易于使用。 但是,我想向 API 用户提供了解为什么无法检查 XML 文档的可能性(例如:DocumentBuilderFactory 无法创建 DocumentBuilder 对象),而不会让他们因必须处理的大量检查异常而感到不知所措。
我对此设计的担忧是:
a)使用单一异常类型(即 IllegalStateException)返回每个可能捕获的异常以指示执行检查失败是一个好主意吗?我会说是,因为用户该函数有两件事除外:
- 了解 XML 文档的格式是否良好。
- 了解函数无法返回答案的情况(例如由于异常)函数未能提供答案的原因。
b) 如果 a) 的答案是否定的,那么最合适的异常名称或解决方案是什么以及为什么?
问候,
I wonder if using an IllegalStateException in this scenario is a good design choice for an API.
Scenario:
I have a function which checks if an XML document is well formed with the following signature:
public boolean isXMLDocumentWellFormed(InputStream inXMLDocument)
This function uses the following snippet to load the XML document:
boolean isXMLDocWellFormed = false;
// Setup document builder
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
.newInstance();
if (docBuilderFactory == null)
throw new IllegalStateException(
"The DocumentBuilderFactory cannot be instanciated");
try {
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
// Parse document
Document doc = docBuilder.parse(inXMLDocument);
if (doc != null)
isXMLDocWellFormed = true;
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new IllegalStateException(e);
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new IllegalStateException(e);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new IllegalStateException(e);
}
return isXMLDocWellFormed;
The API is designed to be very easy to use. However, I would like to provide to API users the possibility to know why an XML document cannot be checked (example: DocumentBuilderFactory cannot create a DocumentBuilder object) without overwhelming them with tons of checked exception that they will have to deal with.
My concerns regarding this design are:
a) Does using one single Exception type (i.e IllegalStateException) to return every possible caught exceptions to indicate a failure to perform the check a good idea ? I would say yes since users would except 2 things out of this function:
- To know if the XML document is well formed or not.
- To know in the event that the function cannot return the answer (due to an exception for instance) why the function failed to provide the answer.
b) If the answer to a) is no, then what would be the most appropriate exception name or solution and why ?
Regards,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我对人们的第一个建议是不要仅仅为了有效地重新抛出而捕获异常。抓住你真正可以对它们做点什么的时候。所以想一想。但是在您捕获已检查异常并将其包装在运行时异常中的示例中,我会问一个问题 - 这种情况发生的频率是多少?如果异常可能很常见(或严重),那么您希望程序员确保他们处理它们,因此检查是可行的方法。但是,如果它们不常见(并且不严重),那么抛出包装运行时可能是可以接受的。这是您需要考虑的事情,因为没有什么比意外的异常更让开发人员烦恼的了。
说了这么多:-),如果你要换行,我会考虑创建你自己的异常,因为你想清楚它是你的,而不是 Java 的。您甚至可以创建一个层次结构,其中包含扩展运行时的通用异常,然后创建更具体的扩展通用异常的层次结构。因此,API 用户可以选择在不同级别进行捕获。
My first recommendation to people is to not catch exceptions just to effectively re-throw. Catch when you can actually do something about them. So think about that. But in your example where you are catching checked exceptions and wrapping them in a runtime exception, I'd ask the question - how often will this occur? If the exceptions are likely to be common (or serious) then you want programmers to ensure that they deal with them, so checked is the way to go. However if they are not common (and not serious) then throwing a wrapping runtime may be acceptable. This is something that you need to think about because nothing annoys a developer more than unexpected exceptions.
Having said nothing by saying all that :-) if you are going to wrap I'd consider creating your own exception because you want to be clear that it is yours and not Java's. You could even create a hierarchy with a generalised exception extending runtime, and then more specific ones extending your genralised exception. Thus allowing API users the option to catch at different levels.
如果您开发的是一个 API,那么您应该将所有异常包装在一个主异常中。这样你就不会泄露实现细节。然而,您的个人品味可能会有所不同
,但我认为 IllegalStateException 不太适合这里。它非常通用并且不能解释问题(IO 异常是非法状态?)。最好的解决方案是创建您自己的自定义异常类并抛出它。
作为您或其他任何人的辅助节点,如果您抛出异常,请不要打印异常。
If its an API that your developing then you should wrap all exceptions in one main exception. This way you don't bleed implementation details. However your personal taste may differ
However I don't think IllegalStateException fits well here. Its very generic and doesn't explain the problem (An IO Exception is Illegal state?). Best solution is to create your own custom Exception class and throw that.
As a side node to you or anyone else, please don't print the exception if your throwing it.
我建议让例程泄漏四种类型的异常可能是最有帮助的:
由数组索引越界等原因引起的异常可能属于上述任何类别。重要的不是访问了越界索引,而是它对其他对象意味着什么。捕获、包装和重新抛出将是一种非常有用的模式,因为将异常解析为上述类别之一将使调用者更好地了解如何处理它。
I would suggest that it's probably most helpful to have a routine leak four types of exceptions:
An exception caused by something like an out-of-bounds array index could fall into any of the above categories. What matters is not that an out-of-bounds index was accessed, but rather what it means about other objects. Catch, wrap, and rethrow would be a very useful pattern, since resolving an exception into one of the above categories will give the caller a much better idea what to do with it.