黑马程序员技术交流社区

标题: 内部类的一个问题 [打印本页]

作者: 甘家利    时间: 2013-3-1 22:47
标题: 内部类的一个问题
本帖最后由 甘家利 于 2013-3-2 16:45 编辑

内部类中为什么访问局部变量要加final,而访问全局变量不用加final,有点不明白?
作者: 陈圳    时间: 2013-3-1 23:08
对于普通局部变量他的作用域就是该方法内,当方法结束该局部变量就随之消失;造成局部内部内调用变量失败,finlly修饰局部变量会使它即使脱离他所在的方法继续存在。看完下面的例子你就明白了.:  
public class ClosureTest   
{  
public static void main(String[] args)  
{  
  //定义一个局部变量  
  final String str = "Java";  
  //在内部类里访问局部变量str  
  new Thread(new Runnable()  
  {  
   public void run()  
   {  
    for (int i = 0; i < 100 ; i++ )  
    {  
     //此处将一直可以访问到str局部变量  
作者: 黄玉昆    时间: 2013-3-1 23:16
你可以看看这个帖子啊,是别人问的,是同类型的问题。你可以看看:http://bbs.itheima.com/thread-38319-1-1.html,或者在论坛里搜索一下关于final的相关问题,都会出现的。
解释如下:
在java中,方法是一种状态,是不能被存储的,对象才是真正被存储在堆内存中的。匿名内部类是在内部,是局部的,它所处的外部环境即方法,在执行完后就不存在了,但是内部类作为一个对象,是有可能被存储下来的。而局部变量也是如此,局部变量时存在于栈内存中的,使用完了就立即被消灭掉了,而匿名内部类访问局部变量,也是对它的一个拷贝而已;那么试想,局部变量都没了,匿名内部类还存在,这个匿名内部类要去哪找这个变量啊,她找不到局部变量这孩子,多着急,只能让虚拟机报警了(编译失败)。所以就要将这个局部变量变为永久的常量才行。
作者: 张亚青    时间: 2013-3-2 14:39
主要有两方面原因:
一、如果局部变量不是final类型的,会造成内部类对象访问一个不存在的局部变量的结果。
        造成这种结果的根本原因是作用域中变量的生命周期导致的。
        局部变量的生命周期和局部内部类的对象的生命周期不一致!
        比如在方法f()中存在局部变量i和内部类InnerClass,并且创建InnerClass的对象innerObject,对象innerObject中调用变量i,当方法f()运行结束后,变量i死亡了,但是内部类的对象innerObject依然存在,这时就会产生一个结果:内部类对象innerObject中要访问一个已经不存在的变量i。
二、为了保持外部类中的局部变量和内部类访问时的一致性。
        内部类中访问外部变量是使用的一种copy  local  variable的方式,即把定义为final的变量拷贝过来用,如果不是final类型,当外部方法改变原始局部变量,而内部类改变复制品时,就不能保证数据的一致性了。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2