局部内部类访问局部变量时,变量必须用final修饰

直接看例子:

public class Test{	
	public void play() {
		int x=4;
		class InTest{
			public void f() {
				System.out.println(x);
			}
		}
		new InTest().f();
	}
	public static void main(String[] args) {
		Test t=new Test();
		t.play();
		
	}
}

此时的局部内部类(定义在方法中的内部类)InTest中的f()访问了外部类中的局部变量x。这里x并没有用final修饰(1.8之后java隐式的将x修饰为final)如果你添加一个x=8,这里就会报错。

为什么要用final修饰

主要原因还是生命周期:当我的t.play()出栈后,play中的局部变量
就会随之销毁,但是我的内部类对象可能仍然还存在的(当不在被使用才会被垃圾回收器回收)这时在内部类中访问了局部变量x,但此时的x已经被销毁,内部类访问了一个并不会存在的变量,这就形成了一个矛盾。根本原因就是:内部类的生命周期比局部变量的长

其实如果我们编译Test.java文件发现会出现两个class文件,Test.class和Test$InTest.class文件,java会将Test中的局部变量x复制一份到TestInTest.class中当做是内部类的成员常量。这样我们访问的其实就是复制的那个成员常量。

如何保证数据的一致性:当我们修改局部变量的时候如何保证被复制出来的变量也会同步一致:用final修饰。这样只要这个局部变量进栈初始化的时候就是一个常量。在生命周期内不能被改变,这里注意生命周期。这样就保证了内部类的成员变量和方法的局部变量的一致性。

public void play(final int a){
	class InTest{
		public void f(){
			System.out.println(a);
		}
	}
	new InTest().f();
	}
	public static void main(String[] args) {
		Test t=new Test();
		t.play(6);
		t.play(7);
	}
}

这样是可以的,因为局部变量a的生命周期是play()方法,随着方法的出栈局部常量也会随之销毁。下一次在进栈的时候又会重新初始化常量的值。

参考:https://blog.csdn.net/sf_climber/article/details/78326984

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值