class Outer
{
void m1()
{
int a=12;
class Inner
{
void show()
{
System.out.println(a);
}
}
new Inner().show();
}
}
这里当我编译这段代码时,我得到的错误是局部变量a是从内部类中访问的;需要宣布最终。但是这里“int a”是一个局部变量,所以为什么我们需要在内部类中声明为final。
答案 0 :(得分:3)
如果局部变量在内部类中使用,则需要声明它final
。对于要在这样的内部类中使用的局部变量,后台的Java接受局部变量的副本并使其成为隐式实例变量,以便内部类可以访问它。因为它是副本,如果值更改,副本可能是错误的。因此,编译器会强制您将其设为final
。
请注意,在Java 8中,这将编译,因为a
是“有效的最终” - 未声明为final
,但在初始化后从未更改过。
在内部类中使用但未声明的任何局部变量,形式参数或异常参数必须声明为final或者是有效的final(§4.12.4),否则在尝试使用时会发生编译时错误。
如果局部变量或方法,构造函数,lambda或异常参数未声明为final,则它实际上是final,但它永远不会作为赋值运算符的左手操作数(第15.26节)或作为前缀的操作数发生或后缀增量或减量运算符(§15.14,§15.15)。
此外,如果满足以下所有条件,则声明缺少初始值设定项的局部变量实际上是最终的:
未宣布为最终版。
每当它作为赋值运算符的左操作数出现时,它肯定是未赋值的,并且在赋值之前没有明确赋值;也就是说,它绝对是未赋值的,并且在赋值的右手操作数之后没有明确赋值(§16(Definite Assignment))。
它永远不会作为前缀或后缀的操作数增加或减少运算符。
答案 1 :(得分:0)
您可以通过将最终变量声明为数组来轻松解决此问题:
final int x[] = {2};
然后从内部类中设置数组值(方法调用返回值的示例):
x[0] = methodcall();
或(仅将值设置为 10 的示例):
x[0] = 10;