在已检查的异常中包装未经检查的异常

时间:2013-11-25 12:08:51

标签: java exception-handling

将Unchecked异常包装到Checked异常中是否可取?

为什么会这个问题?

我正在创建一个API,它将所有已检查的异常包装到API特定的已检查异常中。所以我想知道未经检查的异常是否也可以包含在已检查的异常中。

对此有任何建议吗?如果它们可以被包裹起来,那么如果用一种可以理解的情况进行说明就会很棒。

4 个答案:

答案 0 :(得分:4)

Checked exceptions应该用于可以合理地恢复呼叫者的条件。通过抛出已检查的异常,您强制调用者在catch clause中处理异常或向外传播它。通过捕获Exception并采取适当的恢复步骤,可以从异常情况中恢复API用户。

例如,FileNotFoundExceptionchecked exception

try {
    FileInputStream fis = new FileInputStream(file);
    } catch (FileNotFoundException e) {
    // HANDLE THE EXCEPTION
}

此处即使找不到该文件,如果用户具有适当的恢复步骤(从不同位置读取文件等),也可以继续执行该应用程序。

另一方面,Runtime exceptions应该用来表示无法恢复,继续执行会造成更多伤害。很多时候,runtime exceptions用于表示违反前提条件:API的客户违反了已定义为使用您的API的合同。

例如,ArrayIndexOutOfBoundsExceptionruntime 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以包含未检查的异常。 我希望我的实现的第一个选项是在需要时重用超级引用。

相关问题