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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

方法中的内部类能不能访问方法中的局部变量,为什么?
希望有代码例子

12 个回复

倒序浏览
祝楼主快乐,大家一齐讨论!
回复 使用道具 举报
完全支持你,大家都会顶你

点评

没人给支招啊。。。  发表于 2015-4-23 08:47
回复 使用道具 举报
内部类的生命周期和方法中的局部变量是不一样的,内部类是也是一个类,是存储在堆中,也只有当对该类的引用消失时,内部类才会消亡。而方法的局部变量是存储在堆栈中的,当调用结束时就会退栈,即在内存中这个属性就消失了。也就是说,内部类的生命周期超过了方法中局部变量的生命周期,内部类可能会调用到已经消失的属性,因此内部类不能访问方法中的局部变量。
解决方法就是在局部变量前加修饰符final
,此时局部变量就会存在堆中,生命周期跟工程的生命周期是一样的,此时内部类就可以访问方法中的局部变量。
回复 使用道具 举报
  1. /*
  2. 内部类定义在局部时,
  3. 1,不可以被成员修饰符修饰
  4. 2,可以直接访问外部类中的成员,因为还持有外部类中的引用。
  5.         但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量。
  6. */
  7. class Outer
  8. {
  9.         int x = 3;

  10.         void method(final int a)
  11.         {
  12.                 final int y = 4;
  13.                 class Inner
  14.                 {
  15.                         void function()
  16.                         {
  17.                                 System.out.println(y);
  18.                         }
  19.                 }
  20.        
  21.                 new Inner().function();
  22.                
  23.         }
  24. }


  25. class  InnerClassDemo3
  26. {
  27.         public static void main(String[] args)
  28.         {
  29.                 Outer out = new Outer();
  30.                 out.method(7);
  31.                 out.method(8);
  32.         }

  33. }
复制代码
回复 使用道具 举报
如果上面的无法理解,回过头来找到关于堆栈示意图的知识,好好复习一下,自己画画图。

点评

嗯嗯感觉这个知识点有点琐碎。  发表于 2015-4-23 22:53
回复 使用道具 举报
楼上给出了正解,我就不多说什么了
就是那么一点:类存储空间在堆内存空间,而方法中的变量存储在栈内存空间,如果类去访问方法中已经被释放了的变量,所以不能直接访问
方法中的变量加上final修饰符后,也存储在堆内存空间,就可以访问了
回复 使用道具 举报
不能,因为方法中的内部类的生命周期可能比方法中的局部变量的生命周期要长。
内部类存储在堆内存中,只有当对内部类的全部引用消失时,内部类才会被垃圾回收。
而方法中的局部变量存储在栈内存当中该方法的栈帧中,当该方法执行完毕,栈帧会弹出,局部变量也会跟着消失。
如果在方法执行完毕后,方法中的内部类还能被其他地方引用,
那么方法中的内部类的生命周期就会比方法中的局部变量要长,此时局部变量已经消失,当然就更不可能访问到。
如果局部变量被final修饰,方法中的内部类就能访问这个局部变量了。

下面的代码演示方法中的内部类的生命周期比方法中的局部变量长的情况:
当代码执行到主函数的第二行,调用show方法执行完毕后,show方法中x变量已经在内存中消失。
而此时内部类Inner的引用inner仍然保留,仍然能调用print方法,如果print方法能访问x,此时将产生不可预知的结果。
  1. interface InnerInterface{
  2.         public void print();
  3. }

  4. //外部类
  5. class Outer{
  6.         Object inner;
  7.         //外部类成员方法
  8.         public InnerInterface show(){
  9.                 //方法中的局部变量
  10.                 int x=2;
  11.                 final int y=3;
  12.                
  13.                 //方法中的内部类
  14.                 class Inner implements InnerInterface{                       
  15. //                        int z=x;//方法中的内部类的成员变量也不能访问方法中的局部变量,否则编译报错                       
  16.                         public void print(){
  17. //                                System.out.println(x);//方法中的内部类的成员函数中,也不能访问方法中的局部变量,否则编译报错
  18.                                 System.out.println("y="+y);//可以访问被final修饰的变量
  19.                         }
  20.                 }
  21.                
  22.                 return new Inner();
  23.         }
  24. }

  25. public class Test1 {
  26.         public static void main(String[] args){
  27.                 //调用show方法,执行完毕后,show方法中x变量已经在内存中消失
  28.                 InnerInterface inner= new Outer().show();
  29.                 //而此时内部类Inner的引用inner仍然保留,仍然能调用print方法
  30.                 inner.print();
  31.         }
  32. }
复制代码



点评

谢谢  发表于 2015-4-23 15:42
回复 使用道具 举报 2 0
看着代码太多了,解释那么麻烦?
回复 使用道具 举报
局部变量加final修饰可以
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马