【问题标题】:Try with resource why cannot modify resource尝试使用资源为什么不能修改资源
【发布时间】:2020-02-08 09:59:36
【问题描述】:

我发现了一个尝试将引用扫描的值设置为 null 时无法编译的资源示例

try(Scanner scan = new Scanner(System.in)) {
    String s = scan.nextLine();
    System.out.println(s);
    scan = null;
}

我问这个编译错误背后的规则是什么,我在网上做了一些搜索,但我没有找到解释它的规则 感谢您的任何解释:=)

【问题讨论】:

  • 可能是因为否则try 需要执行一些操作,例如保存对资源的单独引用,以防万一用户尝试重新分配它,但这有点愚蠢。它还会导致代码混乱,在块结束时并不完全清楚资源是否将自动关闭。如果资源引用被重新分配,前一个对象是否仍应关闭?那么引用指向的新对象呢?
  • 假设您可以为try(..){ 中声明的资源分配其他值,例如try(PrintWriter pw = new PrintWriter(...)){pw.write("something"); .. pw = PrintWriter(...); }。在这种情况下,您有两个 PrintWriter 实例。应该为哪一个资源尝试生成负责关闭它的代码?如果您只选择一个(无论哪个),其中一个将没有负责关闭它的代码,这会适得其反并且违背了资源尝试的想法。这就是为什么其中使用的参数必须是最终的或实际上是最终的。
  • try with resources 将尝试关闭扫描,在这种情况下,这意味着在空指针上调用 close()。所以这是一件好事,你不能这样做。这是尝试将资源视为块的最终变量的原因之一
  • @LeedMx 在关闭try-with-resource 变量之前总是有一个null 检查,所以这不是问题。其实你可以用null初始化一个变量,这个block就可以顺利执行了

标签: java java-8 try-catch variable-assignment try-with-resources


【解决方案1】:

这是设计使然。您不能重新分配 final 变量。

14.20.3. try-with-resources

在资源规范中声明的变量如果未显式声明 final,则隐式声明 final(第 4.12.4 节)。

【讨论】:

  • 值得一提的是,try-with-resources 不需要声明变量。它也可以接受已经存在的变量,即使它们不是最终的,例如PrintWriter pw = new PrintWriter("path/to/file"); try(pw){ pw.write("foo"); }。但它也要求这些变量不会被重新分配(即使在 try-with-resource 块之外) - 它们需要实际上是最终的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-03
  • 2022-09-27
  • 1970-01-01
  • 1970-01-01
  • 2021-03-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多