Java匿名内部类或者闭包访问外部(局部)变量,为何需被标志为f
2019-01-25 本文已影响0人
鹅鹅鹅_
原因是:因为局部变量和匿名内部类的生命周期
不同。
匿名内部类是创建后是存储在堆中的,而方法中的局部变量是存储在Java栈中,当方法执行完毕后,就进行退栈,同时局部变量也会消失。那么此时匿名内部类还有可能在堆中存储着,那么匿名内部类要到哪里去找这个局部变量呢?
为了解决这个问题编译器为自动地帮我们在匿名内部类中创建了一个局部变量的备份,也就是说即使方法执结束,匿名内部类中还有一个备份,自然就不怕找不到了。
但是问题又来了。如果局部变量中的a不停的在变化。那么岂不是也要让备份的a变量无时无刻的变化。为了保持局部变量与匿名内部类中备份域保持一致。编译器不得不规定死这些局部域必须是常量,一旦赋值不能再发生变化了。所以为什么匿名内部类应用外部方法的域必须是常量域的原因所在了。
特别注意:在Java8中已经去掉要对final的修饰限制,但其实只要在匿名内部类使用了,该变量还是会自动变为final类型(只能使用,不能赋值)。