A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始




结帖率:66.67%



楼主发表于:2011-11-15 10:40:46




Java code
//DemoClass.java
public class DemoClass{
    public static void main(String[] args){
        DemoClass dc = new DemoClass();
        dc.setI();
        System.out.println(dc.i);


    }
    int i = 10;
    void setI(){
        final int m = 0; //
        class D{
        
            void sI(){
                m = 20; //在内部类中访问局部变量m,为啥要m要位final型的呢?
            }
        
        }
        new D().sI();
   
   
    }


}


评分

参与人数 1技术分 +1 收起 理由
老罗 + 1

查看全部评分

4 个回复

倒序浏览
这一道题有这样的解释,
  int i = 10;
   void setI(){
   final int m = 0; //
   class D{
     
  void sI(){
   m = 20; //在内部类中访问局部变量m,为啥要m要位final型的呢?
   }
     
  }
   new D().sI();   
  }

局部变量有作用范围是很小的,只是在花括号里面
不是整个类
说的很对,因为sun公司考虑的很周全,你这种写法,M是不是final对程序没有什么区别,那为什么编译器让你把m变成final呢,因为sun考虑到局部变量有作用范围是很小,假如内部类使用到了线程去访问局部变量,这样当方法结束了,内部类线程并没有结束,而方法结束,局部变量的值将会销毁,这样将导致内部类线程使用到一个没有声明的变量,这样将会会出错。
例如
   class D extends Thread{
   public void run(){
//try....catch不写了
Thread.sleep(5000);
m ++;
}

   void sI(){
   m = 20;  
  }
想想这样将出现什么后果


我自己回答吧,,,真是的,,,好无聊,,,,

评分

参与人数 1技术分 +2 收起 理由
admin + 2

查看全部评分

回复 使用道具 举报
这个例子很精典,内部类线程并没有结束,而方法结束,局部变量的值应该没有被销毁,而是被改变,这样结果就无法预测,所以sun公司就规定内部类访问局部变量时必须声明为final。

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
不是final的局部变量,你的方法结束了就没了,但是你的内部类和你的方法却不是同时执行的,比如实现ActionListener,当你事件发生的时候才会执行,这时你的方法已经结束了,ActionListener到哪里去找这个局部变量呢,所以要把变量定义为final。希望你能够明白!

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
因为局部变量的生命周期较短,使用过之后就消失了,

而局部类的对象是一个生命周期比较长的,

用一个比较长的生命周期就访问一个比较短的周期

这是肯定不行的,所以必须加上final
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马