原文:https://www.javacodegeeks.com/10-best-practices-to-handle-java-exceptions.html
本文是处理 Java 异常的最佳实践。
Java 中的异常处理并不是一件容易的事,因为新手很难知道应该去抛出或者处理哪些 Java 异常,资深的开发人员也会花费很长时间去确认哪些异常应该抛出、哪些异常应该处理。
如果你是一个新手,那你很可能会对Java 异常处理中出现的各种情况感到迷惑和不解。
本文展示了十个处理Java 异常的重要方法。异常,是指程序执行期间发生的异常情况。下面让我们一起来讨论一下处理 Java 异常的最佳实践。
catch (NoSuchMethodException e) {
return null;
}
如果你不了解失败的真正原因,那你就没有办法阻止这种失败的再次发生。
如果不处理异常,直接返回 ”null” 。这样它就会吞掉异常,而你也就无法了解到为什么会失败,那么这个错误会一直存在,失败也会再次发生。
public void foo() throws Exception { // 错误的方式
}
如果代码中需要抛出异常,那一定不要使用上述代码。
Exception 是所有异常的父类,它会将其他抛出的异常都进行覆盖,异常信息也不够具体,从而无法对于特定的异常进行处理。如果需要抛出很多的异常,我们就要去声明可以由方法抛出的特定异常,这样才可以更好的去针对某个异常进行处理。
public void foo() throws SpecificException1, SpecificException2 { // 正确的方式
}
try {
someMethod();
}
catch (Exception e) {
LOGGER.error("method has failed", e);
}
如果按照上述代码捕获异常,用户调用方法产生的新异常都会包含在其中,那开发人员就没办法对特定的新异常进行处理。
一旦有用户调用方法出现了特定的新异常,那永远也发现不了是哪儿的问题、无法进行修复。代码中如果一直存在没有修复的问题,那运行时就会再次崩溃。
Throwable 的子类包含 java 错误,所以直接捕获 Throwable 会导致很严重的问题。
Java 虚拟机不可能不发生错误、也无法控制发生什么样的错误、无法决定何时发生错误。所以在可能出现的最坏情况下,Java 虚拟机可能对 catch 子句中的任何错误都不进行处理。
catch (NoSuchMethodException e) {
throw new MyServiceException("Some information: " + e.getMessage()); //Incorrect way
}
上述代码中,仅靠抛出异常的信息,无法进行堆栈的跟踪。可以修改为:
catch (NoSuchMethodException e) {
throw new MyServiceException("Some information: " , e);
//Correct way
}
catch (NoSuchMethodException e) {
LOGGER.error("Some information", e);
throw e;
}
在上面代码中,看似很合理,但实际上,抛出和记录同一个异常会导致日志文件中输出多条日志消息,这样在开发人员想通过查看日志来解决问题的时候,就会带来很大的困难。
try {
someMethod(); //Throws exceptionOne
}
finally {
cleanUp(); //如果最后也抛出一个异常,那么exceptionOne将永远丢失
}
如果可以保证 cleanUp() 永远不抛出异常,那上述代码就没问题。
当 someMethod() 抛出了异常,并且在 finally 块中的 cleanUp() 也抛出了异常,那从 cleanUp() 中抛出的异常会把 someMethod() 抛出的异常覆盖,那第一个异常(someMethod() 抛出的,正确的原因)将永远丢失。
catch (NoSuchMethodException e) {
throw e; //避免这样做,因为这样做没有什么用
}
永远不要捕获你不能处理的异常是一个基本概念。
在你可以处理某个异常的时候,再去捕获它。可以考虑在该异常中附加额外的信息对其进行处理。但如果你在 catch 块中无法对它进行处理,那就不要捕获它。
在代码中使用 printStackTrace() ,它不会附加任何上下文信息,这样其他人完全不知道怎么去使用它,也就无法对这些堆栈进行跟踪。
try {
someMethod(); //Method 2
}
finally {
cleanUp(); // 这里做清理
}
如果你调用 someMethod() ,它抛出了异常,但是你不想对其处理,只想进行异常的清理,那就可以在 finally 块中进行清理,不要在 catch 块中执行。
java 异常处理是必不可少的,并且有很多方法都可以很好的去处理这些异常。最近出现的VPN应用漏洞,就是Google 从他们的平台上删除了一些顶级VPN之后才解决。据研究人员称,这个危险漏洞具有支持中间人(MITM)攻击的能力,因此黑客可以很简单的利用它来阻止提供商和用户之间的通信,甚至可以使所有用户无法连接真正的 VPN 服务器,直接重定向到黑客的危险服务器。谷歌为了避免用户受到漏洞攻击,把一些顶级VPN删除了。研究人员通过 Google Play 安全奖励计划 (GPSRP) 发布了公告, 安全分析师利用GPSRP发现了安装量超过 1 亿次的应用程序的漏洞,所以Google 确认此类漏洞仍然存在。
本文展示了处理Java 异常的最佳实践。处理Java异常对于初学者和资深的开发人员来说都相当困难,所以学会合理且正确的对其进行处理是非常重要的。