在本文中,作者先容了9个处理惩罚异常的最佳要领与实践,以举例与代码展示团结的方法,让开拓者更好的领略这9种方法,并指导读者在差异环境下选择差异的异常处理惩罚方法。
以下为译文:
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语句。
利用Finally
对比于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); } } } }
Java 7的Try-With-Resource语句
另一个选择是Try-With-Resource语句,在introduction to Java exception handling中更具体地说明白这一点。
假如你的资源实现了AutoCloseable接口,昆山软件开发,就可以利用它,这正是大大都Java尺度资源所做的。当你在try子句中打开资源时,它将在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,制止抛出一个不详细的异常。
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. 利用描写性动静抛出异常
这一最佳实践的理念与前两个相似。但这一次,你不消给挪用要领的人提供信息。异常动静会被所有人读取,同时必需相识在日志文件或监督东西中陈诉异常时产生了什么。
因此,应该尽大概精确地描写问题,并提供相关的信息来相识异常事件。