常见的局部类包括匿名内部类或局部内部类,如下:
匿名内部类:
- 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博客