黑马程序员技术交流社区
标题:
为什么内部类访问局部变量必须加final修饰?
[打印本页]
作者:
Jarc
时间:
2016-9-11 16:48
标题:
为什么内部类访问局部变量必须加final修饰?
能不能给我举一个说明下,谢谢
作者:
wosika
时间:
2016-9-11 17:19
因为类是加载到方法区中。而局部变量是随意方法的进栈而产生,随着方法的弹栈而消失,所以在局部内部类访问局部变量时,要给局部变量给final修饰使其变成常量,进入常量池,生命周期变长。
作者:
zzdhm
时间:
2016-9-11 17:35
内部类的生命周期和方法中的局部变量是不一样的,内部类是也是一个类,是存储在堆中,也只有当对该类的引用消失时,内部类才会消亡。
* 而方法的局部变量是存储在堆栈中的,当调用结束时就会弹栈,就是在内存中这个属性就消失了。
* 内部类的生命周期超过了方法中局部变量的生命周期,内部类可能会调用到已经消失的属性,因此内部类不能直接访问方法中的局部变量。
* 解决方法:局部变量前加修饰符final,此时局部变量就会存在堆中,生命周期和内部类的生命周期是一样的,此时内部类就可以访问方法中的局部变量。
如以下代码中 局部变量 num就要被 final修饰. jdk1.8可以不需要写final修饰,不过会系统会默认添加final修饰
class Outer {
public void method() {
final int num = 10;
class Inner {
public void print() {
System.out.println(num);
}
}
Inner i = new Inner();
i.print();
}
作者:
15835811325
时间:
2016-9-11 18:03
内部类 可以当作是整个类的一个方法 ,,,, 当方法被调用的时候,, , 他会在堆内存中创建一个对象,,,,,,局部变量是在栈内存中的, , , 不在一个地方 ,,,生命周期也不一样,, ,, , 就像 我来了 你刚走 , ,, , 会出现这种访问不到的错误 , , 所以 把局部变量用final 修饰 ,,, , 修饰之后, , , 他就变成了 常量 , , ,在方法区的静态常量池里, 在类加载的 时候, , 他就存在了,,,,,而且 被类中的所有对象所共享,,,,内部类也可以看作是外部类的一个对象,,,,,, 这样的话 , , ,, ,就可以访问,,,,而不会报错了
作者:
383412263
时间:
2016-9-11 20:41
在方法中创建内部匿名类时,一般是作为callback接口的实现而创建的,可能方法已经执行完了局部变量生命周期结束了,之后如果callback触发了,就可能引起变量引用丢失等内存访问不一致。
而加上final后,编译器是这样处理内部类的。如果这个外部局部变量是常量,则在内部类代码中直接用这个常量。如果是类的实例,则编译器将产生一个内部类的构造参数,将这个final变量传到内部类里,这样即使外部局部变量无效了,还可以使用。
内部类并不是直接调用方法传进来的参数,而是内部类将传进来的参数通过自己的构造器备份到了自己的内部,自己内部的方法调用的实际是自己的属性而不是外部类方法的参数。
这样理解就很容易得出为什么要用final了,因为两者从外表看起来是同一个东西,实际上却不是这样,如果内部类改掉了这些参数的值也不可能影响到原参 数,然而这样却失去了参数的一致性,因为从编程人员的角度来看他们是同一个东西,如果编程人员在程序设计的时候在内部类中改掉参数的值,但是外部调用的时 候又发现值其实没有被改掉,这就让人非常的难以理解和接受,为了避免这种尴尬的问题存在,所以编译器设计人员把内部类能够使用的参数设定为必须是 final来规避这种莫名其妙错误的存在。
作者:
NewsmallWhite
时间:
2016-9-11 20:57
总的来说就是一句话,延长变量的生命周期
作者:
MarsBong
时间:
2016-9-11 23:03
主要就是他们的生命周期不同造成的
作者:
一不小心
时间:
2016-9-11 23:10
方法加载进栈,当方法弹栈,方法内的变量,也会消失,当内部类访问的方法的局部变量时,而此时该方法应弹栈,程序将无法运行。如果用final修饰数据就会被加载到常量池中,内部类随时可以访问。一句话就是为了延长变量的生命周期。
作者:
爱你一万年
时间:
2016-9-11 23:10
又多了一点知识
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2