发布于2026-07-14 阅读(0)
扫一扫,手机访问
Ja va 局部内部类想要访问外层方法的局部变量,有个硬性要求:这些变量必须是 有效 final(effectively final)。简单说,就是变量虽然没有显式加上 final 关键字,但从初始化之后,就再也不能被修改了。
这背后涉及到 JVM 的内存模型。局部变量是存储在方法栈帧里的,方法执行完,栈帧销毁,变量也就没了。但局部内部类的对象可能活得更久——比如被返回出去或者被其他线程引用。这时候内部类要访问那个已经“消失”的变量怎么办?JVM 的做法是:在创建内部类对象时,把变量的值复制一份,存在内部类自己的实例里。为了保证内外数据一致,就得保证这个值在复制之后不会变。所以,干脆要求变量不可变,从根本上避免不一致的问题。
setXxx() 方法去改变引用本身,但可以调用对象内部的方法修改其内容。String、Integer),只要不重新赋值就满足条件。ArrayList),允许调用 add()、remove() 等方法修改对象内部状态,但绝不能把变量指向另一个新对象。下面这种写法,编译直接报错:
void method() {
String s = "hello";
s = "world"; // 修改了,不再是 effectively final
class Local { void print() { System.out.println(s); } } // 编译失败
}
而这样写,就完全没问题:
void method() {
String s = "hello"; // 没再改过
class Local { void print() { System.out.println(s); } } // 编译通过
}
如果拿不准某个变量是不是 effectively final,有个简单粗暴的办法:给它加上 final 关键字试试。如果编译通过,说明它本来就是 effectively final;如果编译器报错“无法为 final 变量赋值”,那就说明你之前确实修改过它,需要调整逻辑。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8