Android中未声明final的局部变量为何可在ClickListener中生效?
为什么未声明final的局部变量能在匿名内部类中正常使用?
你遇到的这个情况,核心是Java 8引入的**实质final(effectively final)**规则,加上匿名内部类的变量捕获机制,具体拆解如下:
- 实质final的自动识别:Java 8之前,匿名内部类访问外部局部变量必须显式加
final修饰,但Java 8之后,只要变量在初始化后从未被修改过,编译器会自动将其视为“实质final”的变量,允许在匿名内部类或Lambda表达式中访问。你代码里的String a = "a";,初始化后再也没被重新赋值,完全符合这个规则,所以不用写final也能正常编译运行。 - 变量捕获的底层逻辑:你担心的“onCreate执行完变量销毁”是对局部变量生命周期的误解。当匿名内部类访问外部局部变量时,会在内部类对象中创建一个该变量的副本——如果是基本类型,拷贝的是值;如果是引用类型(比如这里的String),拷贝的是对象的引用。onCreate方法执行完毕后,原局部变量a确实会被销毁,但内部类对象已经持有了
"a"这个字符串对象的引用(字符串在常量池里,生命周期很长),所以点击按钮触发onClick时,依然能通过这个引用拿到字符串并显示。
你可以做个测试:如果在setOnClickListener之后加一行a = "b";,编译器立刻会报错,这就证明了只有变量保持“实质final”的状态,才能被匿名内部类访问。
内容的提问来源于stack exchange,提问作者Devpiaa
相关产品推荐
相关产品推荐

