【发布时间】:2021-02-24 19:42:35
【问题描述】:
我想在 Java 9 中使用 try-with-resources 增强功能,方法是将引用变量放在 try with resources 中,而不是整个变量声明。我也知道要做到这一点,我必须遵守规则:Variable used as a try-with-resources resource should be final or effectively final。首先我将尝试使用本地变量,然后使用实例变量。
- 局部变量:
-我将变量设为final,它遵循给定的规则并编译得很好:
public static void main (String[] args) throws IOException{
final FileWriter fw = new FileWriter ("test.txt");
try(fw) {
//some code
}
}
-如果我还删除了 final 关键字,它将再次编译,因为 fw 被认为是实际上是最终的 - 仅初始化一次且从不变异的变量。
public static void main (String[] args) throws IOException{
FileWriter fw = new FileWriter ("test.txt");
try(fw) {
//some code
}
}
- 实例变量:
但是同样的模式也适用于实例变量吗?让我们试试吧。
-首先让我们创建实例变量final,它再次遵循规则并且编译良好:
public class Test {
final FileWriter fw = new FileWriter ("a.txt");
void m1() throws IOException {
try(fw ) {
//some code
}
}
}
-如果我删除 final 关键字,它应该再次编译,不是吗?因为我没有在任何地方改变fw,而是只初始化一次 - 应该是有效的最终。不幸的是,这不起作用:
public class Test {
FileWriter fileWriter = new FileWriter ("a.txt");
void m1() throws IOException {
try(fileWriter) {
//some code
}
}
}
它给我的信息是:用作 try-with-resources 资源的变量应该是最终的或实际上是最终的。所以在这一切之后,我回到我的第一个问题。实例变量是否可以实际上是最终的,或者该术语仅用于局部变量?正如我刚刚展示的那样,我从不改变变量(应该将其视为实际上是最终的),但编译器从不威胁它。
【问题讨论】:
-
只有局部变量才能有效地为final。
-
我怀疑这与可能访问它的子类有关。如果你把它设为私有,它还会抱怨吗?
-
@Gus 是的,它仍然在抱怨。
-
在 Java 中,没有访问修饰符意味着默认访问,这意味着该包中的任何类都可以访问该数据成员。因此,它不是有效的 final 仅仅因为它没有从声明类本身修改。它可以在类外修改。它基本上对包是 PUBLIC。
-
@hfontanez 完全有道理。所以我的回答是,正如 Andreas 所说,只有局部变量才是有效的最终变量?
标签: java variables final try-with-resources effectively-final