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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 甘家利 中级黑马   /  2013-3-1 22:47  /  1284 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 甘家利 于 2013-3-2 16:45 编辑

内部类中为什么访问局部变量要加final,而访问全局变量不用加final,有点不明白?

4 个回复

倒序浏览
对于普通局部变量他的作用域就是该方法内,当方法结束该局部变量就随之消失;造成局部内部内调用变量失败,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局部变量  
回复 使用道具 举报
你可以看看这个帖子啊,是别人问的,是同类型的问题。你可以看看:http://bbs.itheima.com/thread-38319-1-1.html,或者在论坛里搜索一下关于final的相关问题,都会出现的。
解释如下:
在java中,方法是一种状态,是不能被存储的,对象才是真正被存储在堆内存中的。匿名内部类是在内部,是局部的,它所处的外部环境即方法,在执行完后就不存在了,但是内部类作为一个对象,是有可能被存储下来的。而局部变量也是如此,局部变量时存在于栈内存中的,使用完了就立即被消灭掉了,而匿名内部类访问局部变量,也是对它的一个拷贝而已;那么试想,局部变量都没了,匿名内部类还存在,这个匿名内部类要去哪找这个变量啊,她找不到局部变量这孩子,多着急,只能让虚拟机报警了(编译失败)。所以就要将这个局部变量变为永久的常量才行。
回复 使用道具 举报
主要有两方面原因:
一、如果局部变量不是final类型的,会造成内部类对象访问一个不存在的局部变量的结果。
        造成这种结果的根本原因是作用域中变量的生命周期导致的。
        局部变量的生命周期和局部内部类的对象的生命周期不一致!
        比如在方法f()中存在局部变量i和内部类InnerClass,并且创建InnerClass的对象innerObject,对象innerObject中调用变量i,当方法f()运行结束后,变量i死亡了,但是内部类的对象innerObject依然存在,这时就会产生一个结果:内部类对象innerObject中要访问一个已经不存在的变量i。
二、为了保持外部类中的局部变量和内部类访问时的一致性。
        内部类中访问外部变量是使用的一种copy  local  variable的方式,即把定义为final的变量拷贝过来用,如果不是final类型,当外部方法改变原始局部变量,而内部类改变复制品时,就不能保证数据的一致性了。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马