将Unchecked异常包装到Checked异常中是否可取?
为什么会这个问题?
我正在创建一个API,它将所有已检查的异常包装到API特定的已检查异常中。所以我想知道未经检查的异常是否也可以包含在已检查的异常中。
对此有任何建议吗?如果它们可以被包裹起来,那么如果用一种可以理解的情况进行说明就会很棒。
答案 0 :(得分:4)
Checked exceptions
应该用于可以合理地恢复呼叫者的条件。通过抛出已检查的异常,您强制调用者在catch clause
中处理异常或向外传播它。通过捕获Exception
并采取适当的恢复步骤,可以从异常情况中恢复API用户。
例如,FileNotFoundException
是checked exception
:
try {
FileInputStream fis = new FileInputStream(file);
} catch (FileNotFoundException e) {
// HANDLE THE EXCEPTION
}
此处即使找不到该文件,如果用户具有适当的恢复步骤(从不同位置读取文件等),也可以继续执行该应用程序。
另一方面,Runtime exceptions
应该用来表示无法恢复,继续执行会造成更多伤害。很多时候,runtime exceptions
用于表示违反前提条件:API的客户违反了已定义为使用您的API的合同。
例如,ArrayIndexOutOfBoundsException
是runtime exception
:
int[] aa = new int[2];
int ii = aa[2]; // java.lang.ArrayIndexOutOfBoundsException
因为访问数组元素的契约表明数组索引必须介于零和数组长度减去1之间,并且我们违反了上述前提条件。
再次假设您正在编写一个Address
课程,如下areaCode
不能null
。如果有人在没有Address
的情况下创建了areaCode
,那么在使用Address
时,将来可能会造成更大的伤害。在这里,您可以使用IllegalArgumentException
(这是一个运行时异常)来表示:
public class Address {
private String areaCode;
public Address(String areaCode) {
if (areaCode == null) {
throw new IllegalArgumentException("Area Code cannot be NULL");
}
this.areaCode = areaCode;
}
...
}
因此,建议在可能进行恢复的地方使用checked exceptions
,如果无法恢复或有任何违反前提条件,最好使用Runtime exception
。
答案 1 :(得分:0)
一条建议:不要使用CheckedExceptions!总是试着让你自己的Exception从RuntimeException继承,让你的API用户可以选择是否喜欢对异常作出反应!
这是一篇描述问题的博文:http://jandiandme.blogspot.de/2013/05/why-javas-checked-exceptions-are-issue.html
编辑:请你评论你的downvote!答案 2 :(得分:0)
我正在创建一个API,它将所有已检查的异常包装到一个 API特定的已检查异常。
要实现这一点,如果您未在catch(Runtime e)
之前明确拥有catch(Exception e)
,那么您无论如何都要包装未经检查的异常。除非有特殊要求单独处理Runtime
例外,否则通常会遵循哪种IMO。
服务可以将运行时和已检查的异常捕获到服务级别异常,以便调用者只处理可能具有自定义属性,代码等的ServiceException
。
一个例子可能是有一个适用于IO API的服务方法:
public void serviceA(String path) throws ServiceException {
try {
File f = new File(path); //Runtime - NPE etc
Reader r = .. //Checked IOException, may be some Runtime exception
}catch(Exception e) { //both runtime and checked
throw new ServiceException("CUSTOMMSG", e);
}
}
在这里,处理Runtime
异常将是非常具体的情况,因为服务合同是通过ServiceException
,调用者理解并且不知道如何处理Runtime
例外。
答案 3 :(得分:0)
@Narendra,您的API中的Parent类可以扩展Exception类,以便您的API将已检查和未选中的异常包装在一起。或者,您可以创建新的API扩展RuntimeException以包含未检查的异常。 我希望我的实现的第一个选项是在需要时重用超级引用。