欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

9处理Java异常的最佳做法

程序员文章站 2022-03-27 09:58:29
...

  转:

  tuicool/articles/RvAjEzB

  9处理Java异常的最佳做法

  无论您是全新的还是老专业人士,总是要了解异常处理方法,以确保您和您的团队能够处理问题。

  Java中的异常处理不是一个容易的话题。初学者很难理解,甚至有经验的开发人员可以花几个小时讨论如何以及应该抛出哪些异常。

  这就是为什么大多数开发团队都有自己的一套关于如何使用它们的规则。而如果你是一个新的团队,你可能会惊讶于这些规则与以前使用的规则有何不同。

  然而,大多数团队都使用了几种最佳做法。以下是9个最重要的帮助您启动或改进异常处理的功能。

  1.在最后的块中清理资源或使用资源资源语句

  在您尝试块中使用资源(如InputStream),您需要关闭之后,经常会发生这种情况。在这些情况下,常见的错误是关闭try块末尾的资源。

  public void doNotCloseResourceInTry(){

  问题是,只要没有异常被抛出,这种方法似乎工作得很好。try块中的所有语句都将被执行,资源被关闭。

  但是你添加了try块的原因。你调用一个或多个可能引发异常的方法,或者你自己抛出异常。这意味着你可能没有到达try块的结尾。因此,您不会关闭资源。

  因此,您应该将所有清理代码放入finally块或使用try-with-resource语句。

  使用最后的块

  与try块的最后几行相反,finally块总是被执行。这可能在成功执行try块之后或在catch块中处理异常之后发生。因此,您可以确保清理所有打开的资源。

  public void closeResourceInFinally(){

  Java 7的试用资源声明

  另一个选项是在我的Java异常处理介绍中更详细地介绍的try-with-resource语句。

  如果您的资源实现了AutoCloseable接口,则可以使用它。这是大多数Java标准资源。当您在try子句中打开资源时,在try块执行完毕或处理异常之后,它将自动关闭。

  public void automaticallyCloseResource(){ File file=new File(“./tmp.txt”); try(FileInputStream inputStream=new FileInputStream(file);){ //使用inputStream读取文件

  2.喜欢具体例外

  更具体的是你抛出的异常越好。请记住,不知道您的代码的同事或者几个月内的同事需要调用您的方法并处理异常。

  因此,请确保为他们提供尽可能多的信息。这使您的API更容易理解。因此,您的方法的调用者将能够更好地处理异常,或者通过额外的检查来避免这种异常。

  所以,总是尝试找到最适合你的异常事件的类,例如抛出一个NumberFormatException而不是IllegalArgumentException。并避免抛出非特异性异常。

  public void doNotDoThis () throws Exception {

  3.记录您指定的异常

  无论何时在方法签名中指定异常,您还应该在Javadoc中记录它。这与以前的最佳做法具有相同的目标:尽可能提供呼叫者尽可能多的信息,以便他可以避免或处理异常。

  因此,请确保向您的Javadoc 添加一个@throws声明,并描述可能导致异常的情况。

  / **

  4.用描述性消息抛出异常

  这种最佳做法背后的想法与以前的两个相似。但是这一次,您不会向调用者提供您的方法的信息。每个必须理解在日志文件或监视工具中报告异常时发生的情况的人都会读取异常消息。

  因此,应该尽可能准确地描述问题,并提供最相关的信息来了解特殊事件。

  不要误会我 你不应该写一段文字。但您应该在1-2个短句中解释异常的原因。这有助于您的操作团队了解问题的严重性,并且您还可以更轻松地分析任何服务事件。

  如果你抛出一个特殊的异常,它的类名很可能已经描述了这种错误。因此,您不需要提供大量其他信息。一个很好的例子就是NumberFormatException。当您以错误的格式提供String时,它将被类java.lang.Long的构造函数抛出。

  尝试 {

  NumberFormatException类的名称已经告诉你这种问题。它的消息只需要提供导致问题的输入字符串。如果异常类的名称不具有表达性,则需要在消息中提供所需的信息。

  17:17:26,386 ERROR TestExceptionHandling:52 - java.lang中。NumberFormatException:对于输入字符串:“xyz”

  抓住最具体的例外

  大多数IDE可以帮助您实现这一最佳实践。当您尝试首先捕获QQ靓号卖号较少特定的异常时,它们报告无法访问的代码块。

  问题是只有匹配异常的第一个catch块被执行。所以,如果你首先遇到了一个IllegalArgumentException,你将永远不会到达应该处理更特定的NumberFormatException的catch块,因为它是IllegalArgumentException的一个子类。

  总是首先捕获最特定的异常类,并将较少具体的catch块添加到列表的末尾。

  您可以在以下代码段中看到一个这样的try-catch语句的示例。第一个catch块处理所有NumberFormatException,第二个所有的IllegalArgumentException不是NumberFormatException。

  public void catchMostSpecificExceptionFirst () { try {

  不要抓住扔掉

  Throwable 是所有异常和错误的超类。你可以在catch子句中使用它,但你不应该这样做!

  如果您在一个catch子句中使用Throwable,它将不仅捕获所有异常; 它也将捕获所有错误。错误由JVM抛出,表示不是由应用程序处理的严重问题。典型的例子是OutOfMemoryError或*Error。这两种都是由于不在应用程序控制之外的情况引起的,无法处理。

  所以,除非你绝对确定你处于一个特殊的情况,你可以或需要处理一个错误,那么最好别抓住一个Throwable。

  public void doNotCatchThrowable () { try { // do something

  7.不要忽略异常

  你有没有分析过一个错误报告,只有你的用例的第一部分被执行?

  这通常是被忽略的异常引起的。开发人员可能非常确定它永远不会被抛出,并添加了一个不处理或记录的catch块。当你发现这个块时,你很有可能找到一个着名的“永远不会发生”的评论。

  public void doNotIgnoreExceptions () { try { // do something

  那么你可能会分析一个不可能发生的问题。

  所以,请不要忽视一个例外。你不知道代码将来会如何改变。有人可能会删除防止异常事件的验证,而不会发现这会导致问题。或者抛出异常的代码被改变,现在抛出同一个类的多个异常,调用代码并不能阻止它们的所有异常。

  你应该至少写一个日志消息,告诉大家刚刚发生的不可思议的事情,有人需要检查它。

  public void logAnException () { try { // do something

  8.不要登录和投掷

  这可能是这个列表中最常被忽视的最佳实践。您可以找到许多代码片段甚至是异常被捕获,记录和重新引导的库。

  尝试 { new Long(“xyz”);

  在发生异常时可能会感到直观,然后重新抛出异常,以便调用者可以适当地处理异常。但它会为同一个异常写入多个错误消息。

  17 :44 :28,945 ERROR TestExceptionHandling :65 - 的java .lang .NumberFormatException:对于 输入 字符串: “ XYZ ” 的异常 在 线程 “ 主 ” 的java .lang .NumberFormatException:对于 输入 字符串: “ XYZ ” 在 java的.lang .NumberFormatException .forInputString(NumberFormatException .java :65)在 java .lang .Long .parseLong(Long .java :589)在 java .lang .Long。(Long .java :965)at com .stackify .example .TestExceptionHandling .logAndThrowException(TestExceptionHandling .java :63)at com .stackify .example .TestExceptionHandling .main(TestExceptionHandling .java :58)

  附加消息也不添加任何信息。如最佳实践#4所述,异常消息应描述异常事件。堆栈跟踪告诉你抛出异常的是哪个类,方法和行。

  如果需要添加其他信息,您应该捕获异常并将其包装在一个自定义的信息中。但请务必遵循第9号最佳做法。

  public void wrapException (String input) throws MyBusinessException { try { // do something

  所以,只有当你想处理它时才会捕获异常。否则,在方法签名中指定它,并让呼叫者照顾它。

  9.不用消耗它来排除异常

  有时更好地捕捉标准异常并将其包装到自定义异常中。这种异常的典型示例是应用程序或框架特定的业务异常。这允许您添加其他信息,还可以为异常类实现特殊处理。

  当您这样做时,请确保将原始异常设置为原因。该异常类提供了接受一个特定的构造方法的Throwable作为参数。否则,您将丢失原始异常的堆栈跟踪和消息,这将使得难以分析导致异常的异常事件。

  public void wrapException (String input) throws MyBusinessException { try { // do something

  概要

  如你所见,当你抛出或捕获异常时,你应该考虑很多不同的事情。他们大多数的目标是提高代码的可读性或API的可用性。

  异常通常是错误处理机制和通信介质。因此,您应该确保与您的同事讨论您要应用的最佳做法和规则,以便每个人都理解一般概念并以相同的方式使用它们。

  1、具有1-5工作经验的,面对目前流行的技术不知从何下手,

  需要突破技术瓶颈的可以加。2、在公司待久了,过得很安逸,

  但跳槽时面试碰壁。需要在短时间内进修、跳槽拿高薪的可以加。

  3、如果没有工作经验,但基础非常扎实,对java工作机制,

  常用设计思想,常用java开发框架掌握熟练的,可以加。

  4、觉得自己很牛B,一般需求都能搞定。

  但是所学的知识点没有系统化,很难在技术领域继续突破的可以加。

  5. 群号:高级架构群 606187239备注好信息!

  6.阿里Java高级大牛直播讲解知识点,分享知识,

  多年工作经验的梳理和总结,带着大家全面、

  科学地建立自己的技术体系和技术认知!