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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 布鲁Go 中级黑马   /  2013-12-4 16:02  /  2452 人查看  /  14 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 布鲁Go 于 2013-12-4 16:54 编辑

我们知道,内部类定义在局部时,不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量。
比如:
  1. class Outer
  2. {
  3.         int x = 3;

  4.         public void method(final int a)
  5.         {
  6.                 //final
  7.                 int y = 4;
  8.                 class Inner
  9.                 {
  10.                         void function()
  11.                         {
  12.                                 System.out.println(y+","+a+ ","+x);
  13.                         }
  14.                 }
  15.         
  16.                 new Inner().function();
  17.                
  18.         }
  19. }


  20. class  MyInnerClassDemo3
  21. {
  22.         public static void main(String[] args)
  23.         {
  24.                 Outer out = new Outer();
  25.                 out.method(7);
  26.                 out.method(8);
  27.         }
  28. }
复制代码
比如上面的程序,07行   我故意把final 注释掉的话。。是会报错的。。
但是。。在当定义在局部的类是匿名内部类时,如下:

  1. abstract class AbsDemo
  2. {
  3.         abstract void show();        
  4. }
  5. class Outer
  6. {
  7.         int x = 3;
  8.         public void function()
  9.         {
  10.          new AbsDemo()//这里虽然是匿名内部类,但毕竟是在function内部
  11.                 {
  12.                         int num = 9;//但为什么这里num作为匿名内部类局部的变量,不需要被final修饰。
  13.                         void show()
  14.                         {
  15.                                 System.out.println("num==="+num);//这里就可以直接访问非最终变量num.???
  16.                         }
  17.                 }.show();
  18.         }
  19. }

  20. class MyInnerClassDemo4
  21. {
  22.         public static void main(String[] args)
  23.         {
  24.                 new Outer().function();
  25.         }
  26. }
复制代码
这个是可以运行的:
第10行这个new AbsDemo(){}/为什么可以运行呢? 它也是定义在局部的内部类啊。。求解释。。。。。
(注:以上例子在毕老师09天的。。。InnerclassDemo3和InnerDemo4里面。。。)


评分

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

查看全部评分

14 个回复

倒序浏览
上面的代码是访问外部类的成员函数中的局部变量,下面的是内部类中的成员变量。当然不同。

评分

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

查看全部评分

回复 使用道具 举报
局部内部类,如果访问外部类的局部变量时,那么这个局部变量,需要设置成final类型。代码1
而在内部类内部的变量,和这个没有关系。另外在代码2中的 num相对于这个内部类而言,是成员变量。

评分

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

查看全部评分

回复 使用道具 举报
HAnG 发表于 2013-12-4 16:08
上面的代码是访问外部类的成员函数中的局部变量,下面的是内部类中的成员变量。当然不同。 ...

额。想了好久。。还是没太理解。。。。。下面的匿名内部类,不也是是定义在成员函数function中的么?就也在是外部类outer中的成员函数function的中啊。。他里面的变量num在function是成员变量,但放到outer类中,应该也是成员函数function中的局部变量啊。。。。。跟你的“上面的代码是访问外部类的成员函数中的局部变量”不是一样的访问方式吗?(如果说上面的y对于method是属于局部变量的话,事实上我觉得你这个y属于外部类成员函数局部变量的说法也不对啊。。。y对于method来讲,应该是成员级啊。。放到上面的outer里才局部了。)
回复 使用道具 举报
25343215 发表于 2013-12-4 16:12
局部内部类,如果访问外部类的局部变量时,那么这个局部变量,需要设置成final类型。代码1
而在内部类内部 ...

哦,好吧,我好想有点晕了。。。。
回复 使用道具 举报
因为方法的局部变量位于栈上,只存在于该方法的生命期内。当一个方法结束,其栈结构被删除,局部变量成为历史。但是该方法结束之后,在方法内创建的内部类对象可能仍然存在于堆中!例如,如果对它的引用被传递到其他某些代码,并存储在一个成员变量内。正因为不能保证局部变量的存活期和方法内部类对象的一样长,所以内部类对象不能使用它们。
回复 使用道具 举报
HAnG 发表于 2013-12-4 16:08
上面的代码是访问外部类的成员函数中的局部变量,下面的是内部类中的成员变量。当然不同。 ...

噢噢噢,洗了把脸。。重新想了遍。。懂了。。谢谢。。。
回复 使用道具 举报
Sasson 发表于 2013-12-4 16:29
因为方法的局部变量位于栈上,只存在于该方法的生命期内。当一个方法结束,其栈结构被删除,局部变量成为历 ...

额。。。你这个说的不是我问的。。不过也是我的疑问。。。。。。但是,如你所说。。方法的局部变量位于栈上,但是被final修饰后,也还是在栈上啊。。。为什么就可以访问了呢?
回复 使用道具 举报
Sasson 中级黑马 2013-12-4 17:16:05
9#
被final修饰 就不在栈内存了吧  在方法区
回复 使用道具 举报
HAnG 中级黑马 2013-12-4 19:02:05
10#
其实不用想没那么复杂,你的误解就在于把内部类的成员变量看成了外部类的了。
回复 使用道具 举报
我用一句老毕的话来总结。“内部类可以访问外部类中的成员是因为内部类持有外部类的引用。格式是:Outer.this”。看明白这句话,所有内部类神马的都简单了。
回复 使用道具 举报
本帖最后由 布鲁Go 于 2013-12-4 23:43 编辑
Sasson 发表于 2013-12-4 17:16
被final修饰 就不在栈内存了吧  在方法区

啊,是这样吗。。我才学没久基础不牢。。以为只有static 才可比较牛。。。。
回复 使用道具 举报
http://www.cnblogs.com/transmuse/archive/2010/11/18/1881282.html  
你去看看吧
非常有用
回复 使用道具 举报
Sasson 发表于 2013-12-5 00:26
http://www.cnblogs.com/transmuse/archive/2010/11/18/1881282.html  
你去看看吧
非常有用

嗯嗯。。相当有用。。。非常感谢。。。。
回复 使用道具 举报
这里面有人回答不对,大部分回答正确
class Outer
{
        int x = 3;
        class Inner
        {
            void function()
            {
                    x=5;
                System.out.println(x);
            }
        }
        
}
public class  MyInnerClassDemo3
{
        public static void main(String[] args)
        {
                Outer out = new Outer();
                out.new Inner().function();
               
        }
}
这个程序是对的
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马