java外部类调用匿名内部类_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的,什么意思呢?就是“一刀切”,不让修改了。

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页