无论你是新手照旧资深措施员,温习下异常处理惩罚的实践老是一件功德,因为这能确保你与你的团队在碰着问题时可以或许处理惩罚得了它。
在 Java 中处理惩罚异常并不是一件易事。新手以为处理惩罚异常难以领略,甚至是资深开拓者也会花上好几个小时来接头是应该抛出抛异常照旧处理惩罚异常。
这就是为何大大都开拓团队都拥有一套本身的异常处理惩罚类型。假如你初进团队,你也许会发明这些类型和你曾利用的类型截然不同。
尽量如此,这里照旧有一些被大大都团队所遵循的最佳实践准则。以下9个最重要的实践要领能辅佐你开始举办异常处理惩罚,或提高你的异常处理惩罚程度。
1、在 Finally 中清理资源或利用 Try-With-Resource 语句
在实际开拓中会常常碰着在 try 中利用资源的环境,好比一个 InputStream ,在利用后你需要封锁它。在这种环境下,一个常见的错误是在 try 的尾部封锁了资源。
public void doNotCloseResourceInTry() { FileInputStream inputStream = null; try { File file = new File("./tmp.txt"); inputStream = new FileInputStream(file); // use the inputStream to read a file // do NOT do this inputStream.close(); } catch (FileNotFoundException e) { log.error(e); } catch (IOException e) { log.error(e); } }
这种环境的问题是,只要异常没被抛出,措施就能很好地运行。所有在 try 中的代码都将被正常执行,资源也会被封锁。
可是,用 try 老是有原因的。当你挪用一个或多个大概会抛出异常的要领或本身主动抛出异常时,措施大概会无法达到 try 的尾部。于是在最后,资源将不被封锁。
因为,你应该将所有清理资源的代码放进 finally 中,或利用 try-with-resource 语句。
与 try 对比,无论是 try 中的代码被乐成执行,照旧在 catch 中处理惩罚了一个异常后,Finally 中的代码总会被执行。因此,你可以确保所有已打开的资源都将被封锁。
public void closeResourceInFinally() { FileInputStream inputStream = null; try { File file = new File("./tmp.txt"); inputStream = new FileInputStream(file); // use the inputStream to read a file } catch (FileNotFoundException e) { log.error(e); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { log.error(e); } } } }
你还可以选择 try-with-resource 语句,在我的这篇Java 异常处理惩罚入门中有更为具体的先容。
假如你在资源中实现了 AutoCloseable 接口的话,就可以利用 try-with-resource 语句了,劳务派遣管理系统,这也是大大都 Java 尺度资源的做法。假如你在 try-with-resource 中打开了一个资源,在 try 中的代码被执行或异常处理惩罚后,这个资源将会被自动封锁。
public void automaticallyCloseResource() { File file = new File("./tmp.txt"); try (FileInputStream inputStream = new FileInputStream(file);) { // use the inputStream to read a file } catch (FileNotFoundException e) { log.error(e); } catch (IOException e) { log.error(e); } }
2、抛出更详细的异常
你抛出的异常越详细、越明晰越好。时刻紧记这点,出格是假如有一位并不相识你代码的同事,或几个月后的你需要挪用本身的要领并处理惩罚异常时。
因此,你需要确保提供尽大概多的信息,这会使得你的 API 更易于领略。这样,挪用你要领的人可以更好地处理惩罚异常,从而制止特另外诸如此类的查抄。
所以,应该找到与你的异常事件最切合的类,好比抛出一个 NumberFormatException 而不是 IllegalArgumentException (注:譬喻将参数转换为数值堕落时,应该抛出详细的 NumberFormatException ,而不是笼统的 IllegalArgumentException )。请制止抛出一个不详细的异常。
public void doNotDoThis() throws Exception { ... } public void doThis() throws NumberFormatException { ... }
3、为你的异常编写文档
当你在要领签名中指定一个异常时,你也应该在 Javadoc 中记录它。
所以,请确保在 Javadoc 中增加 @throws 声明,并描写大概会导致异常的环境。
/** * This method does something extremely useful ... * * @param input * @throws MyBusinessException if ... happens */ public void doSomething(String input) throws MyBusinessException { ... }
4、将描写信息与异常一同抛出