我是靠谱客的博主 勤奋冥王星,最近开发中收集的这篇文章主要介绍Java匿名内部类访问外部变量,为何需被标志为final?,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

对于Java语言中的final使用,大家应该很熟悉,可以修饰类,表示不可继承;可以修饰方法,表示不可被子类重写;可以修饰变量,表示不可以被二次赋值。那么,Java匿名内部类访问外部变量,为何需被标志为final?这跟上述三个特性有关系吗?

一、问题的提出

Java编程中,使用匿名内部类访问外部方法的局部变量是一件很常见的事件,比如以下代码,使用匿名内部类设置控件的监听器是再常见不过了,下面的例子中,因为匿名监听器类访问了外部局部变量name,编译器提示name变量必须使用final修饰。


//初始化按钮的监听器
public void initListener(Button btn ){
final int name = "王大锤"; //必须标记为final
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
btn.setText(name); //动态改变按钮的文字
}
});
}

为何name变量需被标志为final?这深层次的原因是什么?为什么有这样一个让人摸不着头脑的规定?

二、解释

  • 这要从闭包说起,匿名内部类和外部方法形成了一个闭包,因此,匿名内部类能够访问外部方法的变量,看起来是一种“天经地义”的事情,Java语言当然也需要实现这种特性,但是这里遇到了一个问题。

  • 匿名内部类的生命周期可能比外部的类要长,因此访问外部局部变量有可能是访问不到的。

  • 那怎么办呢?Java语言为了实现这种特性, 只好将外部的局部变量偷偷的赋值了一份给匿名内部类。那这样匿名内部类就可以肆无忌惮的访问外部局部变量了。

  • 问题又来了,这种通过赋值的形式有一个缺陷,匿名内部类不可以修改“原来的局部变量”,因为是一份“复制品”,修改复制品对原变量没什么影响啊。

  • 那怎么办? Java语言干脆强制要求被匿名内部类访问的外部局部变量必须是final的,什么意思呢?就是“一刀切”,不让修改了。



作者:Mr云台
链接:https://www.jianshu.com/p/609ca1c584ac
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

最后

以上就是勤奋冥王星为你收集整理的Java匿名内部类访问外部变量,为何需被标志为final?的全部内容,希望文章能够帮你解决Java匿名内部类访问外部变量,为何需被标志为final?所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部