简体   繁体   English

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

[英]Wrapping unchecked exception in a checked exception

Is it advisable as a practice to wrap an Unchecked exception into a Checked exception? 作为一种做法,将Unchecked异常包装到Checked异常中是否明智?

Why this question? 为什么提出此问题呢?

I am creating an API which wraps all the checked exceptions into an API specific checked exception. 我正在创建一个API,它将所有已检查的异常包装到API特定的已检查异常中。 So I was wondering whether the unchecked exceptions can also be wrapped in checked exception. 所以我想知道未经检查的异常是否也可以包含在已检查的异常中。

Are there any advises on this? 对此有什么建议吗? If they can be wrapped, it would be great if illustrated with a situation where it can make sense. 如果它们可以被包裹起来,那么如果用一种可以理解的情况进行说明就会很棒。

Checked exceptions should be used for conditions from which the caller can reasonably be recovered. Checked exceptions应该用于可以合理地恢复呼叫者的条件。 By throwing a checked exception, you are forcing the caller to handle the exception in a catch clause or to propagate it outward. 通过抛出已检查的异常,您强制调用者在catch clause处理异常或向外传播它。 The API user can be recovered from the exceptional condition by catching the Exception and taking proper recovery steps. 通过捕获Exception并采取适当的恢复步骤,可以从异常条件中恢复API用户。

For example, FileNotFoundException is a checked exception : 例如, FileNotFoundException是一个checked exception

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

Here even if the file is not found, continued execution of the application would be possible if the user has proper recovery steps in place (reading the file from a different location, etc.). 这里即使找不到文件,如果用户有适当的恢复步骤(从不同的位置读取文件等),也可以继续执行应用程序。

On the other hand, Runtime exceptions should be used to indicate that recovery is not possible and continued execution would do more harm. 另一方面,应该使用Runtime exceptions来指示无法进行恢复,并且继续执行会造成更多伤害。 Many a times, runtime exceptions are used to indicate precondition violations: the contract that has been defined to use your API is violated by the client of your API. 很多时候, runtime exceptions用于指示违反前提条件:API的客户端违反了已定义为使用API​​的合同。

For example, ArrayIndexOutOfBoundsException is a runtime exception : 例如, ArrayIndexOutOfBoundsException是一个runtime exception

int[] aa = new int[2];
int ii = aa[2]; // java.lang.ArrayIndexOutOfBoundsException

because the contract to access elements of an array says that array index must be between zero and the array length minus one, and we have violated that precondition above. 因为访问数组元素的契约表明数组索引必须介于零和数组长度减去1之间,并且我们违反了上述前提条件。

Again, suppose you are writing a class Address as below where the areaCode cannot be null . 再次,假设您正在编写一个类Address ,如下所示,其中areaCode不能为null And if anybody creates an Address without an areaCode , it might do more harm in the future while using the Address . 如果有人在没有areaCode情况下创建了一个Address ,那么将来使用Address时可能会造成更大的伤害。 Here, you can use IllegalArgumentException (which is a runtime exception) to indicate that: 在这里,您可以使用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;
}
...
}

So, it is advisable to use checked exceptions wherever recovery is possible, and if recovery is not possible or if there is any precondition violation, it is good to use Runtime exception . 因此,建议在可能checked exceptions恢复的地方使用已checked exceptions ,如果无法进行恢复或者存在任何先决条件违规,则最好使用Runtime exception

One advice: Don't use CheckedExceptions! 一条建议:不要使用CheckedExceptions! Always try to let your own Exception inherit from RuntimeException to let the user of your API the choice whether he likes to react to an exception or not! 总是试着让你自己的Exception从RuntimeException继承,让你的API用户可以选择是否喜欢对异常作出反应!

Here is a blogpost which discribes the issue: http://jandiandme.blogspot.de/2013/05/why-javas-checked-exceptions-are-issue.html 这是一篇描述该问题的博文: http//jandiandme.blogspot.de/2013/05/why-javas-checked-exceptions-are-issue.html

EDIT: Would you please comment your downvote! 编辑:请你评论你的downvote!

I am creating an API which wraps all the checked exceptions into an API specific checked exception. 我正在创建一个API,它将所有已检查的异常包装到API特定的已检查异常中。

To achieve this, if you are not explicitly having catch(Runtime e) before catch(Exception e) , you are anyway wrapping unchecked exception too. 要实现这一点,如果你没有明确地在catch(Exception e)之前catch(Exception e) catch(Runtime e) catch(Exception e) ,那么你也可以包装未经检查的异常。 Which IMO is generally what is being followed unless there is an specific requirement to treat Runtime exception separately. 除非有单独处理Runtime异常的特定要求,否则通常遵循哪种IMO。

It's fine for a service to catch both runtime and checked exception to a service level exception sothat caller would deal with only ServiceException which might have custom attributes, codes etc. 对于服务来说,捕获运行时和已检查异常到服务级别异常是很好的,因为调用者只处理可能具有自定义属性,代码等的ServiceException

One example could be having a service method which works on IO APIs: 一个例子可能是有一个适用于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);
}
}

Here, dealing with Runtime exception would be very specific case as service contract is via ServiceException which caller understands and would not know how to deal with Runtime Exception. 在这里,处理Runtime异常将是非常具体的情况,因为服务契约是通过ServiceException ,调用者理解并且不知道如何处理Runtime Exception。

@Narendra, Parent class in your API can extend Exception class, so that your API wraps checked and unchecked exception together. @Narendra,API中的Parent类可以扩展Exception类,以便您的API将已检查和未检查的异常包装在一起。 Or you can create new API extending RuntimeException to include un-checked exception. 或者,您可以创建新的API扩展RuntimeException以包含未检查的异常。 I will prefer first option for my implementation to reuse super references where ever required. 我希望我的实现的第一个选项是在需要时重用超级引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM