Java 试用资源为什么不能修改资源

Java 试用资源为什么不能修改资源,java,java-8,try-catch,variable-assignment,try-with-resources,Java,Java 8,Try Catch,Variable Assignment,Try With Resources,我发现了一个try-with-resources示例,当我尝试将引用扫描的值设置为null时,该示例未编译 try(Scanner scan = new Scanner(System.in)) { String s = scan.nextLine(); System.out.println(s); scan = null; } 我问这个编译错误背后的规则是什么,我在网上做了一些搜索,但没有找到解释它的规则 谢谢你的解释:=)这是设计的。您不能重新分配final变量 如果

我发现了一个try-with-resources示例,当我尝试将引用扫描的值设置为null时,该示例未编译

try(Scanner scan = new Scanner(System.in)) {
    String s = scan.nextLine();
    System.out.println(s);
    scan = null;
}
我问这个编译错误背后的规则是什么,我在网上做了一些搜索,但没有找到解释它的规则
谢谢你的解释:=)

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

如果资源规范中声明的变量未明确声明为
final
(§4.12.4),则该变量为隐式声明的
final


可能是因为,否则的话,
try
需要保存一个对资源的单独引用,以防用户试图重新分配它,但这有点愚蠢。这还会导致代码混乱,在代码块结束时无法完全清楚资源是否将自动关闭。如果重新分配了资源引用,是否仍应关闭上一个对象?那么引用指向的新对象呢?假设您可以为
try(…){
中声明的资源分配其他值,比如
try(PrintWriter pw=new PrintWriter(…){pw.write(“某物”);…pw=PrintWriter(…);}
。在这种情况下,您有两个
PrintWriter
实例。对于哪一个使用资源进行的尝试应生成负责关闭它的代码?如果您只选择一个(无论是哪一个)其中一个将不会有代码负责关闭它,这会适得其反,并且与使用资源进行尝试的想法背道而驰。这就是为什么其中使用的参数必须是final或实际上是final。使用资源进行尝试将尝试关闭扫描,在本例中,这意味着调用
close()
在空指针上。因此,您不能这样做是一件好事。这是try with resources将资源视为block@LeedMx在关闭
try with resource
变量之前,总是有一个
null
检查,所以这不是问题。实际上,您可以初始化变量with
null
,并且该块将顺利执行。还值得一提的是,try with resources不需要声明变量。它还可以接受已经存在的变量,即使它们是非最终变量,例如
PrintWriter pw=new PrintWriter(“path/to/file”);try(pw){pw.write(“foo”);}
。但它也要求这些变量不会被重新分配(即使在资源块try-with-resource块之外)——它们必须是有效的最终变量。