通俗地解释为什么Java中局部内部类引用外部类的局部变量必须是final修饰的

首先上一段代码(一言不合就上代码)

public class AreaOuter {

	private int cnt = 1;
	
	public void show() {
		
		// 局部变量,java8开始,如果该变量被内部类引用,java编译器就会默认给该变量加final修饰。
                // 所以,如果该变量需要被内部类引用,虽然可以省略final,但是在实际开发中最好还是加上final。
                // 如果没有被内部类引用,那么java编译器就不会做处理。
		int ib = 2;
		
                // 局部内部类
		final class AreaInner {
			private int ia = 1;
			
			public AreaInner() {
				System.out.println("局部内部类的构造方法");
			}
			
			public void test() {
                         // 如果用到外部的变量ib,则ib为final修饰的
                         System.out.println("ib = " + ib);
  			 System.out.println("ia = " + ia);
  			 System.out.println("cnt = " + cnt);
			}
		}
		
		//调用方法:只能在方法体内部调用,声明局部内部类的引用指向局部内部类的对象
		AreaInner areaInner = new AreaInner();
		areaInner.test();
	}
}

再来解释为什么

首先给出一个结论:生命周期不一致

局部变量ib和内部类AreaInner都是在show方法中声明的,其生命周期在调用show方法之后就结束了。但是,局部变量ib是优先于局部内部类AreaInner声明的,所以局部变量ib的生命周期要长一点。在局部内部类AreaInner引用局部变量ib的时候,实际上会将ib的值拷贝一份拿到内部类使用
这个时候就可能产生一个问题,什么问题呢?假如我在局部内部类AreaInner引用局部变量ib之后,背着AreaInner把ib的值给改变了,结果AreaInner还在傻乎乎地按照改变之前的值运行程序,最终就会导致运行结果出现差错。

所以为了防止这种情况发生,java编译器就会在局部变量的前面加上final修饰。这样一来,ib的值改不了,那么最后局部内部类引用局部变量运行的结果也就不会出现差错。

posted @ 2020-10-18 11:06  凯尔哥  阅读(452)  评论(0编辑  收藏  举报