涨知识-关于局部内部类访问局部变量

局部内部类访问局部变量的问题


局部内部类访问局部变量必须用final修饰
局部内部类在访问它所在方法中的局部变量必须用final修饰,为什么?
因为当调用这个方法时,局部变量如果没有final修饰,它的生命周期和方法的生命周期是一样的,
当方法弹栈时,这个局部变量也会消失。
那么如果局部内部类对象还没有马上消失,想用这个局部变量时,就没有了。如果用final修改时,
会在类加载的时候进入常量池,即使方法弹栈,常量池的常量还在,也可以继续使用。

但jdk1.8取消了这个规则。可以认为是个bug。

class Demo1_InnerClass {
	public static void main(String[] args) {
		Outer o = new Outer();
		o.method();	//当调用method()方法时,就创建Inner对象,执行print方法
	}
}

class Outer {
	public void method() {
		//局部内部类。同局部变量一个意思。只在该方法内有效,出了该方法就访问不到该类。
		//局部内部类,只能在其所在的方法中访问。
		class Inner {
			public void print() {
				System.out.println("Hell Inner");
			}
		}
		
		Inner i = new Inner();
		i.print();
	}
}
-------------------------------------------------
class Outer {
	public void method() {

		final int num = 10;	//jdk1.8以前版本,必须要用final修饰,否则报错	

		//局部内部类。同局部变量一个意思。只在该方法内有效,出了该方法就访问不到该类。
		//局部内部类,只能在其所在的方法中访问。
		class Inner {
			public void print() {
				System.out.println(num);
			}
		}
		
		Inner i = new Inner();
		//这里的print也是用到method里面的num
		i.print();
	}
}
如果每个final会报错,因为后面那个用到method里面的i
如果是常量可以直接去常量池找
如果不是在在对应栈找,但是那个method栈已经弹出了,对应i变量也没了
不过jdk1.8后就不用担心这个问题了,好像会自动添加?

int num的生命周期和method()方法的生命周期是一样。
当method()方法出栈之后,new Inner()对象仍然想使用int num,就无法使用了。

常量池:是方法区的一部分。final修饰的变量是常量,进入常量池,不在栈中。
常量池的作用:延迟变量的生命周期。

你可能感兴趣的:(涨知识系列,java,jvm,开发语言)