黑马程序员技术交流社区

标题: 方法中局部变量加了final后,在内存中运行是什么情况? [打印本页]

作者: hamesksk    时间: 2015-3-23 22:24
标题: 方法中局部变量加了final后,在内存中运行是什么情况?
方法里的内部类,要访问方法里的成员,必须是final
原因是因为内部类的生命周期比局部变量要长
按这种原因解释,那加了final后,方法的局部变量生命周期就变长了吗?


作者: 福娃51zx    时间: 2015-3-23 22:54
同学,加了final之后就是一个常量,不能再改变它的值,生命周期并没有变长,只有加了static(静态)后,生命周期才会变长。
作者: hamesksk    时间: 2015-3-23 23:13
福娃51zx 发表于 2015-3-23 22:54
同学,加了final之后就是一个常量,不能再改变它的值,生命周期并没有变长,只有加了static(静态)后,生 ...

既然生命周期没有变长,那如果内部类还活着,局部变量却已经在堆内存消亡了,还怎么引用?就算是final也消亡了哇。。。。
作者: 福娃51zx    时间: 2015-3-24 16:20
这我就不懂了,抱歉!
作者: liaohongjie    时间: 2015-3-24 17:57
加了final以后,生命周期变长了,直到JVM退出,被final修饰的变量才会消失
作者: 柴达木    时间: 2015-3-24 20:52
内部类和外部类在编译时实际上会生成两个类,outer.class和inner.class
final修饰的局部变量会在内部类对象中复制一个局部变量的副本,为了实现保持内部类访问并使用的局部变量和外部类局部变量之间的一致性,所以要求要用final来修饰局部变量,使其值不能改变。
如果局部变量是基本数据类型的,final的值不可改变,直接拷贝到内部类中;如果是引用数据类型的,则把引用拷贝到内部类对象中,因为final的引用是不可修改的,也就是说会一直存在指向同一值对象的引用,使得被引用的值对象不会被当成垃圾而回收。
这样就避免了因为内部类和外部类中因修改局部变量值、或引用对象被回收而导致产生严重的问题。
个人理解,希望高手给出更详细的回答。
作者: 夜班心桥    时间: 2015-3-24 22:08
  1. class InnerDemo2
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 new Out().show();
  6.         }
  7. }
  8. class Out
  9. {
  10.         public void show() {
  11.                 final int i = 3;
  12.                 class Inner
  13.                 {
  14.                         public void func() {
  15.                                 System.out.println("inner func..." + i);
  16.                         }
  17.                 }

  18.                 new Inner().func();
  19.         }
  20. }
复制代码

其实,很简单。局部变量跟随方法的消亡而消亡,但是对象持续的时间相对来说很长,所以,它无法去访问方法里的局部变量。如果一个变量一旦被final修饰后,该变量就成为了常量。
在编译的时候,编译器做了一个小动作,它会把常量值,直接将3代替func方法中的i,所以,即使局部变量释放了,那个常量值还存在。


作者: 夜班心桥    时间: 2015-3-26 10:22
夜班心桥 发表于 2015-3-24 22:08
其实,很简单。局部变量跟随方法的消亡而消亡,但是对象持续的时间相对来说很长,所以,它无法去访问方法 ...

大家一起努力!




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