【问题标题】:Java try-with resource warning from Eclipse来自 Eclipse 的 Java try-with 资源警告
【发布时间】:2014-01-22 11:38:21
【问题描述】:

为什么对 Eclipse 来说,这要通过 try-with arm 来管理?

BufferedReader reader = null;
try {
  if (condition) {
    try {
      reader = method1();
    } catch (Exception e) {
      ...
    }
  }
  if (reader == null) {
    reader = method2();
  }

  do things ...
} catch(Exception e) {
  ...
} finally {
  if (reader != null) {
    reader.close();
  }
}

有更好的方法来处理这种情况吗?还是只是来自 Eclipse 的垃圾警告?

这种情况无效:

try (BufferedReader reader = null) {
  if (condition) {
    reader = method1();
  } else {
    reader = method2();
  }

  do things ...
}

【问题讨论】:

  • this case is not valid 是什么意思?
  • 你知道你不是catching 可能的例外吗?
  • 您从 eclipse 收到的实际警告消息是什么以及它的放置位置?
  • @ᴍaroun,我正在捕捉它们,并添加到我的示例代码中。谢谢
  • @Pshemo Resource 'reader' 应该由 try-with-resource 管理

标签: java eclipse warnings try-with-resources


【解决方案1】:

试试:

try (BufferedReader reader = createBufferedReader(condition)) {
  do things ...
}

private BufferedReader createBufferedReader(boolean condition){
  if (condition) {
    return method1();
  } else {
    return method2();
  }
}

【讨论】:

  • 这将是有效的,但我并没有创建一种新方法来避免该警告,在我看来似乎用枪杀死了一只蚂蚁。
  • 不要避免警告 - 编写更容易出错和更简洁的代码。这就是您收到警告的原因。
  • 不要争论,但是当我看第一行代码时,我不知道 createBufferedReader 在做什么,而不是回到第一种方法。相反,这肯定不是更简洁的代码。 (显然在 do things ... 行中有很多代码)。
  • 我建议您学习“清除代码”,在团队工作时也是如此。
  • 另一个来源:Martin Fowler,重构,提取方法:refactoring.com/catalog/extractMethod.html
【解决方案2】:

正如jls-14.20.3 中的 Java 语言规范所述

如果在 ResourceSpecification 中声明的资源未显式声明为 final,则该资源被隐式声明为 final(第 4.12.4 节)。

所以你不能在你的 try 块中改变它。如果您希望能够更改它,请使用标准 try-catch-finally 块。其他选项是在将资源与 try-with-resources 一起使用之前决定正确的资源。

【讨论】:

  • 使用标准 try-catch 块会引发警告。
  • @user509375 我无法重现您的警告。
【解决方案3】:

您不一定需要 Seby 的回答中的 Callable 或 lambda 表达式。

鉴于问题很简单,您可以简单地使用三元运算符,它适用于所有 java 版本。

final String s = "abc";

try (BufferedReader reader = (condition) ? method1() : method2();) {

  do things ...

} catch (Exception e) {
  ...
}

【讨论】:

    【解决方案4】:

    您可以使用返回类型为 BufferedReader 的函数,您可以在其中使用条件调用,仅当满足您正在寻找的某些特定条件时,才能从 main 调用此函数。

    private BufferedReader createReader(!XYZ){
    if(a>b)
    return abc();
    else
    return def();
    }
    
    public static void main(String[] args){
    createReader(!XYZ);
    }
    

    【讨论】:

      【解决方案5】:

      恕我直言,简洁明了:

      final String s = "abc";
      
      try (BufferedReader reader = new Callable<BufferedReader>() {
        @Override
        public BufferedReader call() throws Exception {
          if (condition) {
            return method1();
          } 
          return method2();
      
          // different scope, s needs final keyword
        }
      }.call()) {
      
        do things ...
      
      } catch (Exception e) {
        ...
      }
      

      在 java 8 中也更容易:

      String s = "abc";
      
      try (BufferedReader reader = () -> {
        if (condition) {
          return method1();
        } 
        return method2();
      
        // same scope, s does not need final keyword
      }) {
      
        do things ...
      
      } catch (Exception e) {
        ...
      }
      

      【讨论】:

      • 匿名Callable类后需要调用call()
      • 无论如何,恕我直言,在这里使用Callable 是在滥用这个界面。我更喜欢 Puce 的方法和额外的私有方法。这将防止您必须创建最终引用,以便您可以将它们传递给 Callable 匿名类。此外,最好将代码分成可以单独维护的短部分(如方法)。
      • @Pshemo 恕我直言,将代码分成短部分会降低代码的可读性,在小类或小项目中还可以,但经验告诉我,在拥有数百个类的大型团队和大型项目中,这种方法要少得多更可取。即时可读性在任何方面都可以更好地快速理解代码块。
      • @Pshemo 此外,在 java 8 中,“最终”问题消失了。
      猜你喜欢
      • 2013-01-31
      • 2017-11-18
      • 2012-03-04
      • 1970-01-01
      • 2013-09-12
      • 2011-12-28
      • 2017-07-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多