处理 Java 异常的 10 个最佳实践「译文」

原文:https://www.javacodegeeks.com/10-best-practices-to-handle-java-exceptions.html

        本文是处理 Java 异常的最佳实践。

        Java 中的异常处理并不是一件容易的事,因为新手很难知道应该去抛出或者处理哪些 Java 异常,资深的开发人员也会花费很长时间去确认哪些异常应该抛出、哪些异常应该处理。

        如果你是一个新手,那你很可能会对Java 异常处理中出现的各种情况感到迷惑和不解。

        本文展示了十个处理Java 异常的重要方法。异常,是指程序执行期间发生的异常情况。下面让我们一起来讨论一下处理 Java 异常的最佳实践。

1.处理Java异常的最佳实践

1.1 永远不要在 catch 块中吞掉异常

​​​​​​​catch (NoSuchMethodException e) {
   return null;
}

        如果你不了解失败的真正原因,那你就没有办法阻止这种失败的再次发生。

        如果不处理异常,直接返回 ”null” 。这样它就会吞掉异常,而你也就无法了解到为什么会失败,那么这个错误会一直存在,失败也会再次发生。

1.2 声明式的抛出特定异常

public void foo() throws Exception { // 错误的方式
}

        如果代码中需要抛出异常,那一定不要使用上述代码。

        Exception 是所有异常的父类,它会将其他抛出的异常都进行覆盖,异常信息也不够具体,从而无法对于特定的异常进行处理。如果需要抛出很多的异常,我们就要去声明可以由方法抛出的特定异常,这样才可以更好的去针对某个异常进行处理。

public void foo() throws SpecificException1, SpecificException2 { // 正确的方式
}

1.3 不要捕获所有异常,而是捕获特定的子类

try {
  someMethod();
} 
catch (Exception e) {
	LOGGER.error("method has failed", e);
}

        如果按照上述代码捕获异常,用户调用方法产生的新异常都会包含在其中,那开发人员就没办法对特定的新异常进行处理。

        一旦有用户调用方法出现了特定的新异常,那永远也发现不了是哪儿的问题、无法进行修复。代码中如果一直存在没有修复的问题,那运行时就会再次崩溃。

1.4 永远不要捕获任何 Throwable 类

        Throwable 的子类包含 java 错误,所以直接捕获 Throwable 会导致很严重的问题。

        Java 虚拟机不可能不发生错误、也无法控制发生什么样的错误、无法决定何时发生错误。所以在可能出现的最坏情况下,Java 虚拟机可能对 catch 子句中的任何错误都不进行处理。

1.5 准确覆盖自定义异常中的异常,保证堆栈上下文不丢失

catch (NoSuchMethodException e) {
	throw new MyServiceException("Some information: " + e.getMessage());   //Incorrect way
}

        上述代码中,仅靠抛出异常的信息,无法进行堆栈的跟踪。可以修改为:

catch (NoSuchMethodException e) {
  throw new MyServiceException("Some information: " , e);  
  //Correct way
}

1.6 不要又记录又抛出异常

catch (NoSuchMethodException e) {
   LOGGER.error("Some information", e);
   throw e;
}

        在上面代码中,看似很合理,但实际上,抛出和记录同一个异常会导致日志文件中输出多条日志消息,这样在开发人员想通过查看日志来解决问题的时候,就会带来很大的困难。

1.7 不要在 finally 块中抛出异常

try {
  someMethod();  //Throws exceptionOne
}
finally {
  cleanUp();    //如果最后也抛出一个异常,那么exceptionOne将永远丢失
}

        如果可以保证 cleanUp() 永远不抛出异常,那上述代码就没问题。

        当 someMethod() 抛出了异常,并且在 finally 块中的 cleanUp() 也抛出了异常,那从 cleanUp() 中抛出的异常会把 someMethod() 抛出的异常覆盖,那第一个异常(someMethod() 抛出的,正确的原因)将永远丢失。

1.8 只捕获你可以处理的异常

catch (NoSuchMethodException e) {
	throw e; //避免这样做,因为这样做没有什么用
}

        永远不要捕获你不能处理的异常是一个基本概念。

        在你可以处理某个异常的时候,再去捕获它。可以考虑在该异常中附加额外的信息对其进行处理。但如果你在 catch 块中无法对它进行处理,那就不要捕获它。

1.9 不要使用 printStackTrace() 语句

        在代码中使用 printStackTrace() ,它不会附加任何上下文信息,这样其他人完全不知道怎么去使用它,也就无法对这些堆栈进行跟踪。

1.10 使用 finally 块对异常进行清理

try {
  someMethod();  //Method 2
} 
finally {
  cleanUp();    // 这里做清理
}

        如果你调用 someMethod() ,它抛出了异常,但是你不想对其处理,只想进行异常的清理,那就可以在 finally 块中进行清理,不要在 catch 块中执行。

        java 异常处理是必不可少的,并且有很多方法都可以很好的去处理这些异常。最近出现的VPN应用漏洞,就是Google 从他们的平台上删除了一些顶级VPN之后才解决。据研究人员称,这个危险漏洞具有支持中间人(MITM)攻击的能力,因此黑客可以很简单的利用它来阻止提供商和用户之间的通信,甚至可以使所有用户无法连接真正的 VPN 服务器,直接重定向到黑客的危险服务器。谷歌为了避免用户受到漏洞攻击,把一些顶级VPN删除了。研究人员通过 Google Play 安全奖励计划 (GPSRP) 发布了公告, 安全分析师利用GPSRP发现了安装量超过 1 亿次的应用程序的漏洞,所以Google 确认此类漏洞仍然存在。

2. 结论

                本文展示了处理Java 异常的最佳实践。处理Java异常对于初学者和资深的开发人员来说都相当困难,所以学会合理且正确的对其进行处理是非常重要的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值