为什么局部内部类只能访问final变量

 我来答
匿名用户
2017-08-23
展开全部
1)所谓“局部内部类”就是在对象的方法成员内部定义的类。而方法中的类,访问同一个方法中的局部变量,是天经地义的。那么为什么要加上一个final呢?
2)原因是:编译程序实现上的困难,难在何处:内部类对象的生命周期会超过局部变量的生命期。为什么?表现在:局部变量的生命期:当该方法被调用时,该方法中的局部变量在栈中被创建(诞生),当方法调用结束时(执行完毕),退栈,这些局部变量全部死亡。而:内部类对象生命期,与其它类一样,当创建一个该局部类对象后,只有没有其它人再引用它时,它才能死亡。完全可能:一个方法已调用结束(局部变量已死亡),但该局部类的对象仍然活着。即:局部类的对象生命期会超过局部变量。
3)退一万步:局部类的对象生命期会超过局部变量又怎样?问题的真正核心是:如果:局部内部类的对象访问同一个方法中的局部变量,是天经地义的,那么:只要局部内部类对象还活着,则:栈中的那些它要访问的局部变量就不能“死亡”(否则:它都死了,还访问个什么呢?),这就是说:局部变量的生命期至少等于或大于局部内部类对象的生命期。而:正是这一点是不可能做到的
4)但是从理论上:局部内部类的对象访问同一个方法中的局部变量,是天经地义的。所以:经过努力,达到一个折中结果:即:局部内部类的对象可以访问同一个方法中的局部变量,只要这个变量被定义为final.那么:为什么定义为final变可以呢?定义为final后,编译程序就好实现了:具体实现方法是:将所有的局部内部类对象要访问的final型局部变量,都成员该内部类对象中的一个数据成员。这样,即使栈中局部变量(含final)已死亡,但由于它是final,其值永不变,因而局部内部类对象在变量死亡后,照样可以访问final型局部变量。

归纳上述回答的真正核心是:局部内部类对象中包含有要访问的final型局部变量的一个拷贝,成为它的数据成员。因此,正是在这个意义上,final型局部变量的生命期,超过其方法的一次调用。严格来说,方法调用结束,所有的局部变量(含final)全死亡了。但:局部内部类对象中有final型局部变量的拷贝。
Storm代理
2023-08-29 广告
"StormProxies是全球大数据IP资源服务商,其住宅代理网络由真实的家庭住宅IP组成,可为企业或个人提供满足各种场景的代理产品。点击免费测试(注册即送1G流量)StormProxies有哪些优势?1、IP+端口提取形式,不限带宽,I... 点击进入详情页
本回答由Storm代理提供
jv...h@163.com
2017-08-23 · TA获得超过346个赞
知道答主
回答量:398
采纳率:22%
帮助的人:119万
展开全部
那么
内部类引用的变量就是非法的,则该变量必须被final修饰,否则就会因为在调用内部类时因为找不到所用的变量而报错:
如果外部类中的变量d没有被内部类引用,则final为可选的,也就会自动被消除,而内部类却不会离开它所在方法就失去作用,它有更广的生命周期,下面通过一个实例加以说明。
若不定义为final,则
无法通过编译!(
jdk1.6测试过)。
因为编译器不会给非final变量进行拷贝:java编译器的行为是这样的(前提条件是该变量在内部类中被引用):
若定义为final,则java编译器则会在内部类TimerPrint内生成一个外部变量的拷贝:
由上可以看出,在方法内部定义内部类时,内部类如果调用了方法内的变量,但实际编译时,内部类编译为Outer$1TimerPrint.class,这说明,外部类的这个方法和内部类是处于同一级别的:
编译后的外部类class:
编译后的内部类class!start被调用后!
加一个参数d 并且把它定义为非final类型,编译以后文件如下,后来想到应该是生命周期的原因,因为方法内定义的变量是局部变量,离开该方法,变量就失去了作用,非final变量也会随之消失,就会出现内部类引用非法!
实际做法:
如例中所示,而且
java编译器将不做特殊处理!:
外部类编译后的字节码:
内部类编译后的字节码!
下面看经过编译以后的字节码今天编写一个多线程程序,发现在方法内定义内部类时,在外部类Outer中声明了一个内部类TimerPrint,这个类中的方法引用了方法start中的一个局部变量testTxt
逻辑上:因为该内部类出现在一个方法的内部,如果内部类调用了方法中的变量,那么该变量必须申明为final类型,百思不得其解。换句话说是非final变量和内部类的生命周期不一样,而且可以既可以保证内部类可以引用外部属性,又能保证值的唯一性
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式