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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 小黑马 黑马帝   /  2012-9-13 12:23  /  1224 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. public class Demo{
  2.     public static void main(){
  3.     }
  4.     public void test( final String a){  //这个地方为什么必须用final修饰
  5.          class inner{
  6.                 void print(){                 
  7.                         System.out.println(a);
  8.                 }
  9.          }
  10.     }
  11. }
复制代码
问题:  在test方法中 这个a属于局部变量,如果方法内的类要访问这个a,不加final的话会编译报错,那为什么要加上这个final呢才能访问呢?
   
         

5 个回复

倒序浏览
方法内部类对象不能使用该内部类所在方法的非final局部变量:
因为:方法的局部变量位于栈上,只存在于该方法的生命期内。当一个方法结束,其栈结构被删除,局部变量成为历史。但是该方法结束之后,在方法内创建的内部类 对象可能仍然存在于堆中!例如,如果对它的引用被传递到其他某些代码,并存储在一个成员变量内。正因为不能保证局部变量的存活期和方法内部类对象的一样长,所以内部类对象不能使用到非final局部变量。

class Outer {
         public void doSomething(){
             final int a =10;
             class Inner{
                 public void test(){
                     System.out.println(a);
                 }
             }   
             Inner in = new Inner();
             in.test();
        }
         public static void main(String[] args) {
             Outer out = new Outer();
             out.doSomething();
         }
      }
回复 使用道具 举报
2楼的说法并不准确,试想一下,如果局部方法的生命周期结束了,其中定义的final变量也不可能访问到了,栈都清空了,去哪访问该变量呢?

其实,当局部内部类使用了外部的变量的时候,内部类会自己定义一个同类型的变量,然后在构造函数中用外部变量给自己定义的变量赋值,类似于参数的值传递,这样,即使局部方法结束了,内部类依旧可以使用自己定义的变量。

虽然不加final也可以实现,但是如果不加final,外部变量的值就可以改变,如果给内部类赋值以后,外部变量的值变了,但内部类中定义的变量并不会随之变化(因为是值传递的),所以,为了避免这种不一致,才强制使用final。
回复 使用道具 举报
方法中的变量声明为final的,因为这样可以使变量全局化
局部变量的生命期是当该方法被调用时,方法中的局部变量在栈中被创建;当方法调用结束时,释放栈空间。
内部类对象生命期是和其它类一样,创建一个局部内部类对象后,当没有其它类再引用时,它才释放。
所以局部类的对象生命期会超过局部变量。这样即使栈中的局部变量被释放,但final值是不变的。
回复 使用道具 举报
李菁 发表于 2012-9-13 13:23
方法中的变量声明为final的,因为这样可以使变量全局化
局部变量的生命期是当该方法被调用时,方法中的局部 ...

final并不能是局部变量全局化,方法一结束,方法内的final局部变量依然要释放。
内部类使用的变量实际上是方法内局部变量的一个拷贝,所以即使方法结束了,类中的变量依旧可以存在。
回复 使用道具 举报
1、外部类中的方法test 要访问内部类,就必须建立内部类对象。
2、而内部类只能访问被final修饰的局部变量。
3、被final修饰的变量,就像一个常量,只能被赋值一次。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马