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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

  1. package com.study;

  2. interface OutInterface2{        //定义一个接口
  3. }
  4. class OuterClass3 {
  5.         public OutInterface2 doit(final String x){//doit方法参数为final类型
  6.                 //在doit()方法中定义一个内部类
  7.                 class InnerClass2 implements OutInterface2{
  8.                         InnerClass2(String s){
  9.                                 s=x;
  10.                                 System.out.println(s);
  11.                         }
  12.                 }
  13.                 return new InnerClass2("doit");
  14.         }

  15. }
复制代码

搜狗截图20130925144026.png (47.89 KB, 下载次数: 211)

搜狗截图20130925144026.png

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

4 个回复

正序浏览
是变量的作用域的问题,因为匿名内部类是出现在一个方法的内部的,如果它要访问这个方法的参数或者方法中定义的变量,则这些参数和变量必须被修饰为final。因为虽然匿名内部类在方法的内部,但实际编译的时候,内部类编译成Outer.Inner,这说明内部类所处的位置和外部类中的方法处在同一个等级上,外部类中的方法中的变量或参数只是方法的局部变量,这些变量或参数的作用域只在这个方法内部有效。因为编译的时候内部类和方法在同一级别上,所以方法中的变量或参数只有为final,内部类才可以引用。

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报
final是最终的,一直存在的。
public OutInterface2 doit(final String x){//doit方法参数为final类型
定义x为final的就让他一直存在,因为方法中的局部变量是放在栈中的,该方法一调用结束,该方法就消亡了,该方法包括方法里的局部变量都消亡。而内部类本质还是一个类,它的创建时对象在堆内存上创建,当该类不再使用时才消亡。
所以内部类要访问方法中的成员变量,必须要保证方法中的成员变量比内部类存活的时间长。所以必须要
加上final关键字达到这一要求。~

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报
是的,因为内部类对象的生命周期会超过局部变量的生命期。局部变量的生命期:当该方法被调用时,该方法中的局部变量在栈中被创建,当方法调用结束时,退栈,这些局部变量全部死亡。而内部类对象生命期,与其它类一样,当创建一个局部内部类对象后,只有当没有其它人再引用它时,它才能死亡。所以完全可能一个方法已调用结束(局部变量已死亡),但该局部类的对象仍然活着。即:局部类的对象生命期会超过局部变量。
局部内部类的对象访问同一个方法中的局部变量,那么这就要求只要局部内部类对象还活着,那么栈中的那些它要访问的局部变量就不能“死亡”。这就是说:局部变量的生命期至少等于或大于局部内部类对象的生命期。

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报
答案是肯定的,毕老师的视频就有说过
方法中的参数是放在栈中的,方法一结束在内存中就没有了,而内部类是存在堆中,
两者的生命周期不一致会造成安全问题。但如果参数前加了final表示是一直存在,就没这问题了,当然可以调用了

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马