常见的局部类包括匿名内部类或局部内部类,如下:
匿名内部类:
public class test {
//局部final变量a,b
public void test(final int a) {
final int b = 10;
//匿名内部类
new Thread(){
public void run() {
System.out.println(a);
System.out.println(b)
}
}.start()
}
}
局部内部类:
public class OutClass {
private int age = 12;
public void outprint(final int x) {
final int b = 10;
//局部内部类
class InClass {
public void inPrint() {
System.out.println(x);
System.out.println(age)
}
}
new InClass().inPrint();
}
}
原因一:因为生命周期不同,局部变量会在方法结束以后会被销毁,这样会导致内部类引用了一个不存在的变量,这就前后矛盾了。所以编译器会在内部类中生成一个局部变量的拷贝,这个拷贝的生命周期与内部类的对象相同,就不会出现上述的问题。
原因二:但是这样一来就导致了其中一个变量被修改,两个变量值可能会不同的问题,为了解决这个问题,编译器就要求局部变量需要把final修饰,以保证两个变量的值相同。
在JDK8之后,编译器不要求内部类访问的局部变量必须被 final 修饰,但是局部变量的值不能被修改(无论是方法中还是内部类中),否则编译器会提示编译错误。利用java查看编译后的字节码可以发现,编译器已经加上了 final 关键字。
视频讲解:
硬核Java面试题讲解,为什么局部内部类和匿名内部类只能访问局部final变量 - 知乎
面试题9-为什么局部内部类和匿名内部类只能访问局部final变量_哔哩哔哩_bilibili
参考:Java进阶——Java 局部内部类访问局部变量为什么必须加final关键字_内部类访问局部变量 为什么final-CSDN博客