• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

关于java:9种常用便捷的Java异常处理方法帮你脱身繁琐

linux 搞代码 3年前 (2022-03-03) 31次浏览 已收录 0个评论
文章目录[隐藏]

前言

Java中的异样解决是个不简略的话题。初学者很难了解,即便是经验丰富的开发人员也能够破费数小时来探讨如何以及应该抛出或解决哪些异样。

这就是为什么大多数开发团队都有一套对于如何应用它们的规定的起因。而且,如果您是团队老手,那么您可能会感到诧异,这些规定与您以前应用的规定有何不同。

尽管如此,大多数团队还是采纳了几种最佳实际。以下是9个最重要的信息,它们能够帮忙您入门或改善异样解决。

一、在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块的最初几行相同,finally块始终执行。在胜利执行try块之后或在catch块中解决了异样之后,就会产生这种状况。因而,能够确保革除所有关上的资源。

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语句,我在Java异样解决简介中对其进行了具体阐明。

如果您的资源实现了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);
    }
}

二、指定具体的异样

抛出的异样越具体越好。始终牢记,不晓得您的代码,或者可能几个月后不晓得您的代码的共事,须要调用您的办法并解决该异样。

因而,请确保为他们提供尽可能多的信息。这使您的API更易于了解。后果,您的办法的调用者将可能更好地解决该异样,或者通过额定的check防止该异样。

因而,请始终尝试查找最适宜您的异样事件的类,例如,抛出NumberFormatException而不是.

IllegalArgumentException。并防止引发不确定的Exception。

public void doNotDoThis() throws Exception {
    ...
}
public void doThis() throws NumberFormatException {
    ...
}

整顿了一下2021年的Java工程师经典面试真题,共485页大略850道含答案的面试题PDF,蕴含了Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、Redis、MySQL、Spring、Spring Boot、Spring Cloud、RabbitMQ、Kafka、Linux 等简直所有技术栈,每个技术栈都有不少于50道经典面试真题,不敢说刷完包你进大厂,但有针对性的刷让你面对面试官的时候多几分底气还是没问题的。

三、对特定异样进行归档

每当在办法签名中指定异样时,也应在Javadoc中对其进行记录。这与以前的最佳实际具备雷同的指标:为呼叫者提供尽可能多的信息,以便他能够防止或解决异样。

因而,请确保在Javadoc中增加一个@throws申明,并形容可能导致异样的状况。

/**
 * This method does something extremely useful ...
 *
 * @param input
 * @throws MyBusinessException if ... happens
 */
public void doSomething(String input) throws MyBusinessException {
    ...
}

四、抛出异样的时候蕴含形容信息

最佳实际背地的想法与前两个相似。然而这一次,您没有将信息提供给您的办法的调用者。每个必须理解该日志文件或您的监督工具中报告该异样时产生的状况的人都能够浏览该异样的音讯。

因而,它应尽可能精确地形容问题,并提供最相干的信息以理解异样事件。

不要误会我的意思;您不应该写一段文字。然而您应该用1-2个简短的句子来阐明出现异常的起因。这能够帮忙您的经营团队理解问题的严重性,还能够使您更轻松地剖析任何服务事件。

如果抛出特定的异样,则其类名很可能曾经形容了谬误的品种。因而,您无需提供很多其余信息。一个很好的例子是NumberFormatException。当您以谬误的格局提供String时,它将由类java.lang.Long的构造函数引发。

try {
    new Long("xyz");
} catch (NumberFormatException e) {
    log.error(e);
}

NumberFormatException类的名称曾经告诉您问题的类型。它的音讯仅须要提供引起问题的输出字符串。如果异样类的名称不那么具备表现力,则须要在音讯中提供所需的信息。

17:17:26,386 ERROR TestExceptionHandling:52 - java.lang.NumberFormatException: For input string: "xyz"

五、首先捕捉最具体的异样

大多数IDE都能够帮忙您获得最佳实际。当您尝试首先捕捉不太具体的异样时,它们报告无法访问的代码块。

问题在于仅执行与异样匹配的第一个catch块。因而,如果您首先捕捉IllegalArgumentException,那么您将永远不会达到应该解决更具体的NumberFormatException的catch块,因为它是IllegalArgumentException的子类。

始终首先捕捉最具体的异样类,并将不那么具体的捕捉块增加到列表的开端。

您能够在以下代码片段中看到这样的try-catch语句的示例。第一个catch块解决所有NumberFormatException,第二个所有IllegalArgumentException,它们不是NumberFormatException

public void catchMostSpecificExceptionFirst() {
    try {
        doSomething("A message");
    } catch (NumberFormatException e) {
        log.error(e);
    } catch (IllegalArgumentException e) {
        log.error(e)
    }
}

六、不要捕捉Throwable异样

Throwable是所有异样和谬误的超类。您能够在catch子句中应用它,但相对不要这样做!

如果在catch子句中应用Throwable,它将不仅捕捉所有异样,而且还捕捉所有Exception。它还会捕捉所有Error。JVM抛出重大的谬误问题,这些问题不会由利用程序处理。

比如说:OutOfMemoryError或StackOverflowError。

两者都是由应用程序无法控制的状况引起的,无奈解决。

因而,最好不要捕捉Throwable,除非您齐全确定本人处于非凡状况下,在这种状况下您可能或被要求处理错误。

public void doNotCatchThrowable() {
    try {
        // do something
    } catch (Throwable t) {
        // don't do this!
    }
}

七、不要疏忽异样

您是否已经剖析过仅在用例的第一局部失去执行的错误报告?

这通常是由疏忽的异样引起的。开发人员可能十分确定不会将其抛出,并增加了一个不会解决或记录它的catch块。并且,当您找到该块时,您很可能甚至找到了驰名的“这将永远不会产生”正文之一。

public void doNotIgnoreExceptions() {
    try {
        // do something
    } catch (NumberFormatException e) {
        // this will never happen
    }
}

好吧,您可能正在剖析一个不可能产生的问题。

因而,请不要疏忽异样。您不晓得未来的代码将如何更改。有人可能会删除阻止异样事件的验证,而没有意识到这会造成问题。或者,引发异样的代码被更改,当初引发同一个类的多个异样,并且调用代码并不能阻止所有这些异样。

您至多应该写一条日志音讯,通知所有人不可设想的事件刚刚产生,有人须要查看它。

public void logAnException() {
    try {
        // do something
    } catch (NumberFormatException e) {
        log.error("This should never happen: " + e);
    }
}

八、不要记录和抛出

这可能是此列表中最常被疏忽的最佳实际。您能够找到许多代码段,甚至能够找到捕捉,记录和从新抛出异样的库。

try {
    new Long("xyz");
} catch (NumberFormatException e) {
    log.error(e);
    throw e;
}

记录产生的异样,而后将其从新抛出,以便调用者能够适当地解决它,这可能会很直观。然而它将为同一异样写入多个谬误音讯。

17:44:28,945 ERROR TestExceptionHandling:65 - java.lang.NumberFormatException: For input string: "xyz"
Exception in thread "main" java.lang.NumberFormatException: For input string: "xyz"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:589)
at java.lang.Long.(Long.java:965)
at com.stackify.example.TestExceptionHandling.logAndThrowException(TestExceptionHandling.java:63)
at com.stackify.example.TestExceptionHandling.main(TestExceptionHandling.java:58)
在com.stackify.example.TestExceptionHandling.main(TestExceptionHandling.java:58)

其余音讯也不会增加任何信息。如最佳做法4中所述,异样音讯应形容异样事件。堆栈跟踪会告诉您在哪个类,办法和行中引发了异样。

如果须要增加其余信息,则应捕捉异样并将其包装在自定义异样中。然而请确保遵循最佳实际9。

public void wrapException(String input) throws MyBusinessException {
    try {
        // do something
    } catch (NumberFormatException e) {
        throw new MyBusinessException("A message that describes the error.", e);
    }
}

因而,仅在要解决它时才捕捉异样。否则,请在办法签名中指定它,而后让调用者来解决它。

九、在不耗费异样的状况下包装异样

有时最好捕捉一个规范异样并将其包装到自定义异样中。这种例外的典型示例是特定于应用程序或框架的业务例外。这使您能够增加其余信息,还能够对异样类施行非凡解决。

执行此操作时,请确保将原始异样设置为起因。该异样类提供了承受一个特定的构造方法的Throwable作为参数。否则,您将失落堆栈跟踪和原始异样的音讯,这将使剖析导致您的异样的异样事件变得艰难。

public void wrapException(String input) throws MyBusinessException {
    try {
        // do something
    } catch (NumberFormatException e) {
        throw new MyBusinessException("A message that describes the error.", e);
    }
}

总结

综上所述,抛出或捕捉异样时,您应该思考很多不同的事件。他们中大多数人的指标是进步代码的可读性或API的可用性。

异样通常是同时存在的错误处理机制和通信介质。因而,您应该确保与共事探讨要利用的最佳实际和规定,以便每个人都能了解个别概念并以雷同的形式应用它们。


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:关于java:9种常用便捷的Java异常处理方法帮你脱身繁琐

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址