如何解决实例变量可以有效地最终确定吗/ Java中仅局部变量有效地最终确定吗?
我想在Java 9中使用 try-with-resources增强功能,方法是将引用变量放在try的资源中,而不是整个变量的声明中。我也知道,要做到这一点,我必须遵循规则:Variable used as a try-with-resources resource should be final or effectively final
。首先,我将尝试使用local,然后尝试使用实例变量。
- 局部变量:
-我使变量final遵循给定规则,并可以正常编译:
public static void main (String[] args) throws IOException{
final FileWriter fw = new FileWriter ("test.txt");
try(fw) {
//some code
}
}
-如果我还删除了 final 关键字,它将再次编译为fw
,因为它被视为有效的final -仅初始化一次且永不突变的变量。
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
的更改,而只能对其进行一次初始化-应该是有效的final 。不幸的是,这行不通:
public class Test {
FileWriter fileWriter = new FileWriter ("a.txt");
void m1() throws IOException {
try(fileWriter) {
//some code
}
}
}
它给我的信息是:用作资源尝试资源的变量应该是最终的或实际上是最终的。所以毕竟,我要回到我的第一个问题。实例变量可以有效地定为还是该术语仅用于局部变量?正如我刚刚展示的那样,我从未对变量进行过变异(应该将其有效地视为最终变量),但是编译器从未这样威胁它。
解决方法
Java Language Specification的4.12.4. final
Variables部分明确规定,只有局部变量和参数可以有效地定为:
某些未声明为
final
的变量被认为是有效的最终变量:
一个局部变量,其声明符具有一个初始化程序(§14.4.2),如果满足以下所有条件,则有效地是最终的:
声明符缺少初始化程序的局部变量是有效最终变量,如果满足以下所有条件:
未声明为
final
。每当它出现在赋值表达式的左侧时,它肯定是未赋值的,也没有在赋值之前确定赋值;也就是说,在赋值表达式(§16 (Definite Assignment))的右侧之后,它肯定是未赋值的,也不一定是赋值的。
它永远不会作为前缀或后缀递增或递减运算符的操作数出现。
方法,构造函数,lambda或异常参数(§8.4.1,§8.8.1,§9.4,§15.27.1,{{ 3}})的目的是为了确定它是否有效地为终结符,作为其声明符具有初始化程序的局部变量。
如果变量实际上是最终变量,则在其声明中添加
final
修饰符不会引入任何编译时错误。相反,如果删除了final
修饰符,则在有效程序中声明为final
的局部变量或参数将变为有效的最终变量。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。