【问题标题】:try-finally with close auto-refactoring to try-with-resources with codestyle/checkstyle使用 codestyle/checkstyle 自动重构 try-with-resources 的 try-finally
【发布时间】:2023-03-09 22:22:01
【问题描述】:

我正在处理最近从 Java 6 迁移到 Java 7 的代码库。我想替换如下结构:

Connection conn = null;
try{
    conn = new Connection();
    ...
} catch(Exception ex){
    ...
} finally{
    if (conn != null){
        conn.close();
    }
}

使用try-with-resources(从 Java 1.7 开始可用):

try(Connection conn = new Connection()){
    ...
} catch(Exception ex){
    ...
}

是否有一种自动化的方法可以自动将旧的重构为新的(可能使用 Checkstyle 插件,或者在 Eclipse 本身中)?

【问题讨论】:

    标签: java eclipse checkstyle try-with-resources try-finally


    【解决方案1】:

    很难快速改变这一切。请注意,有时finally 中的另一个try-catch 块会捕获关闭资源时引发的异常。

    try-with-resources 语句确实允许您处理资源关闭异常(close 方法抛出的异常将被抑制)。

    我还没有听说过这样的Eclipse 功能,但如果您可能只想为此目的使用IntelliJ IDEA Community Edition IDE。

    #1

    您可以使用以下代码检查功能:

    1. 'try finally' replaceable with 'try' with resources
    2. AutoCloseable used without 'try' with resources

    您只需按 Ctrl+Alt+Shift,输入检查名称并按 Enter。之后,您将看到 IDEA 可以应用此模式的地方,但请注意,它并未涵盖 100% 的情况。

    #2

    另一种方式,更难,但高度可定制的是Structural Search and Replace 功能。您可以定义要更改的结构:

    try {
        $type$ $objectName$ = new $concreteType$($args$)
        $tryStatements$;
    } catch($exceptionType$ $exceptionName$) {
        $catchStatements$;
    } finally {
        $finallyStatements$;
    }
    

    最后的结构:

    try ($type$ $objectName$ = new $concreteType$($args$)) {
      $tryStatements$;
    } catch($exceptionType$ $exceptionName$) {
        $catchStatements$;
    }
    

    在变量设置中,您可以要求 $concreteType$ 实现 AutoCloseable 接口。

    但请注意:

    1. 我在这里摆脱了finally 块并支持单个catch 块。
    2. 还假设每个try-with-resources 块会打开一个资源。
    3. 如前所述 - finally 块中没有异常处理。

    这个模板肯定需要更多的工作,而且可能不值得去做。

    【讨论】:

    • 好吧,老实说,我知道 IntelliJ。我来自 C# 背景,在 Visual Studio 中使用过 ReSharper。后来我听说 IntelliJ 和 ReSharper 来自同一个制造商,所以它们有很多相似的功能。不幸的是,我目前正在从事的项目是在 Eclipse 中。这显然不是首要任务,但我认为如果有一些简单的东西可以同时改变这一切,那就太好了。既然没有,我们就在遇到旧的 try-close_in_finally 时更改它,也许有一天会搜索所有这些以同时更改它们。谢谢
    • @KevinCruijssen 您的项目甚至不需要编译/使用 IntelliJ。您可以将其导入那里,进行替换,保存文件并返回 Eclipse。
    • 好点。将很快安装 IntelliJ 并进行替换。在我目前的工作中,我们会在周五下午进行各种与项目无关的事情,例如重构、新单元测试的代码覆盖率、分享我们遇到的问题/新东西等。现在我会接受你的回答。再次感谢。
    • 你说的一句话让我有点困惑:try-with-resources 语句没有捕获资源关闭异常。但是在页面stackoverflow.com/questions/17739362/… 上说并且 close() 会自动调用,如果它抛出 IOException,它将被抑制(如 Java 语言规范 14.20.3 中所述)。 java.sql.Connection 也是如此,我不确定哪个是正确的,但我相信错误被抑制或忽略了。
    • @KarlHenselin 你是对的,异常会被压制。我的观点是,有时您想处理此类异常,并且使用该语法将不允许您这样做:) 我将编辑答案以使其更具体。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-18
    • 1970-01-01
    • 2020-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-08
    相关资源
    最近更新 更多