黑马程序员技术交流社区

标题: 方法中的内部类能不能访问方法中的局部变量,为什么? [打印本页]

作者: —__    时间: 2012-5-17 10:06
标题: 方法中的内部类能不能访问方法中的局部变量,为什么?
//不能!因为虚拟机不支持会报错。
//除非用final修饰
class Outer{


void method(){
  
  @SuppressWarnings("unused")
  //int y=4; 如此定义局部变量时,编译无法通过,提示必须使用final修饰
  final int y=4;
  
  class Inner{
   void function(){
    System.out.println(y);
   }
  }
  new Inner().function();
  
  
}
}
这里有个疑问那就是为什么虚拟机不支持?
我在网上找了很多关于这个问题的答案,通篇代码下来都是最后验证到虚拟机不支持这一步上
而没有验证为什么虚拟机不支持的这一步。
按理说这样回答就可以了,但是我总感觉回答的有点残缺,就像把问题推卸到了虚拟机上,
但是到底为什么却依然不明白,所以我想知道到底为什么不可以呢?

希望回答的朋友能具体说明下,如果发代码最好能讲解一下,
如果代码只是验证到虚拟机不支持这一步上的话,就不必发了
真心求讲解,奖励50金币

作者: niceBoy    时间: 2012-5-17 10:12
//不能!因为虚拟机不支持会报错。
//除非用final修饰
class Outer{
void method(){
  @SuppressWarnings("unused")
  //int y=4; 如此定义局部变量时,编译无法通过,提示必须使用final修饰
  //作用域問題,局部變量作用方法只在方法里,也就是方法的"{}"之間有用
  //定義成final可以,是因為y就變成了常量,常量當然哪裡都能用,例如:int x =4可以吧,4就是常量

  final int y=4;
  class Inner{
   void function(){
    System.out.println(y);
   }
  }
  new Inner().function();
}
}
作者: —__    时间: 2012-5-17 10:14
niceBoy 发表于 2012-5-17 10:12
//不能!因为虚拟机不支持会报错。
//除非用final修饰
class Outer{


所谓局部变量是作用在整个函数的,而你说的是成员变量 概念完全不对~
作者: 李哲    时间: 2012-5-17 10:21
方法中的内部类能不能访问方法中的局部变量,为什么?

可以,但是只能访问被final修饰的局部变量。原因如下:
方法被调用,局部变量在栈内存中被创建。当方法调用结束,退栈,这些局部变量全部消失。
但是在堆内存创建一个内部类对象后,对象会存在更长的时间,垃圾回收才会使其消失。
很可能方法已调用结束(局部变量已消失),但内部类对象仍然存在。
这样会出现矛盾,依然存在的内部类对象,如何访问消失的局部变量?

使用final修饰的局部变量被复制为内部类对象中的一个数据成员。这样,即使栈内存中局部变量(包括final修饰的局部变量)已死亡。
但由于final,其值不变,内部类对象依然可以访问final修饰的局部变量(通过访问自己内部的由局部变量复制得到的数据成员)。
作者: —__    时间: 2012-5-17 10:32
谢谢 通过你的解答 我了解到 遇到问题不懂得时候应该先画图
作者: 黑马张立国    时间: 2012-5-17 10:56
局部变量伴随着函数入栈而创建,伴随着函数出栈而死亡。
而局部内部类确是生命周期长,当访问以死亡的局部变量时就会报错。
为了能访问局部变量需要被final修饰,表面上说是延长了局部变量的生命。
实际上是每个局部变量拷贝了一份被final修饰的变量,放入到局部内部类的对象中,成为对象的常量数据。
作者: _Xuan    时间: 2012-7-28 15:32
李哲 发表于 2012-5-17 10:21
方法中的内部类能不能访问方法中的局部变量,为什么?

可以,但是只能访问被final修饰的局部变量。原因如 ...

正解!!!




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