这是包含匿名内部类的一段代码:public class test
{
  public static void main(String[] args) {
                  innerB obj=new innerB();   //生成innerB 类对象
(1) Iner obj1=obj.d("gongchang"); //获得接口Iner 的一个引用
obj1.f();           //调用内部类中的f()
(2) obj1=obj.d("wangwei");
obj1.f();
   }
}interface Iner{ public void f( );}   //接口class innerB              //类innerB
{

          String s1="dd";
 
public Iner d(final String s2)    //获取接口引用
{
return new Iner(){         //匿名内部类
public void f()
{
                                     System.out.println(s1);
System.out.println(s2);


}
};
}

}
问题:
1.为什么s2一定要定义为final?如果不是final,会提示:cannot refer to a non-final variable inside an inner class defined in a different method 
    而s1没有这样的强制要求?
2.既然s2必须是final,也就是赋值之后不能再改变,为什么我可以调用两次(1)(2)?这是不是相当于给s2赋值两次?请高手解惑!!!谢谢!~~

解决方案 »

  1.   

    关于1: 使用final是语法要求,不过,为什么这么要求,不是很明白。
    关于2: s2是final指得是在相应得方法内部它是不可改变得,但是你两次调用,赋予不同得值和这个没有关系
      

  2.   

    1.s2一定要定义为final,也就是说,使s2成为常量。因为public Iner d(final String s2){}方法结束后,匿名内部类的对象是活动的,而如果s2是局部变量(不用final定义),则被stack弹出,不存在了。匿名内部类的对象怎么使用不存在的参数呢,所以,要延长s2的生命周期,用final定义它。2、不是。调用两次(1)(2),有了两个s2,各用各的值。
      

  3.   

    to yqj2065:
     谢谢您的留言。
     “而如果s2是局部变量(不用final定义),则被stack弹出,不存在了”
      final+变量,不是仅仅说明变量的值不能改变吗?它 可以改变变量的生命周期吗?经您这么一说,我又一个新的问题:
    类中的静态变量是属于整个类的,它的生命周期应该从类的被加载开始,但它什么时候结束?GC只回收对象,对这种变量应该不处理,是谁最后管理、回收这些资源?
      

  4.   

    to yqj2065(严千钧) :
     谢谢您的留言!
    “2、不是。调用两次(1)(2),有了两个s2,各用各的值。”我想问:内部是如何标识这两个s2?同一个对象,同一个方法中的参数s2
      

  5.   

    问得很好,不过我一下回答不出来,JVM的机制我看了,不太认真。
    您自己查阅一下。
    类的终止好像在《JVM规范》中没有写细节。
      

  6.   

    s2的问题:一般最常用的方法是,将s2copy为相关内部类的private成员变量。简单的说,s2可以看成内部类的private成员变量。
      

  7.   

    第二个问题我也同意楼上的说法
    第一个问题我在看think in java 的时候也想过,问过,最后不了了之了,呵呵,还是比较敬佩楼主的精神
    也请高手继续发表高见
      

  8.   

    to yqj2065(严千钧) 和woso(我是我) :
      谢谢您们的留言!~
      但关于第二个问题,我想再确认一下:
    “s2的问题:一般最常用的方法是,将s2copy为相关内部类的private成员变量。简单的说,s2可以看成内部类的private成员变量。”
    代码:
    public class test
    {
      public static void main(String[] args) {
                      r obj=new r(); 
                      r.f("gongchang");
                      r.f("seven");  
       }
    }class r
    {
    public void f( final String s)
    {
    System.out.println(s);
    }
    }问:这里的做法是不是把s作为类r的一个私有变量(非final型)?
        还有,就是在参数列表中加final限制有什么好处?谢谢!!~~~~~
      

  9.   

    no、no、no:
    class r{
    public void f( final String s){
    System.out.println(s);
    }
    }
    这里的 final可以认为完全没有意义。“在参数列表中加final限制有什么好处?”
    主要是针对该方法中存在局部类的情况。
    s作为类r的方法f的一个“局部”变量,如果有局部类say InF,则s可以视为InF对象的私有成员变量。
    简单的说,没有局部类,final没有意义;有局部类,提供final将变量变成局部类的私有成员变量。BTW:r.f("gongchang"); 改成obj.f("gongchang"); 
    f不是静态方法(即使参数是命名常量)