1. 程式人生 > 其它 >為什麼匿名內部類只能訪問final修飾的變數?

為什麼匿名內部類只能訪問final修飾的變數?

Local classes can most definitely reference instance variables. The reason they cannot reference non final local variables is because the local class instance can remain in memory after the method returns. When the method returns the local variables go out of scope, so a copy of them is needed. If the variables weren’t final then the copy of the variable in the method could change, while the copy in the local class didn’t, so they’d be out of synch.
Anonymous inner classes require final variables because of the way they are implemented in Java. An anonymous inner class (AIC) uses local variables by creating a private instance field which holds a copy of the value of the local variable. The inner class isn’t actually using the local variable, but a copy. It should be fairly obvious at this point that a “Bad Thing”™ can happen if either the original value or the copied value changes; there will be some unexpected data synchronization problems. In order to prevent this kind of problem, Java requires you to mark local variables that will be used by the AIC as final (i.e., unchangeable). This guarantees that the inner class’ copies of local variables will always match the actual values.

原文地址

首先內部類肯定是可以引用例項變數的,他們無法引用非final關鍵字修飾的變數的原因是內部類在方法返回後還會存在記憶體中。當方法返回,方法的區域性變數超出了有效範圍(方法內的變數失效),這時候就需要拷貝一份變數給內部類使用。如果,變數不是final修飾,那麼拷貝的值可能會發生改變,但是拷貝到內部類的變數卻無法同步更新。
匿名內部類要求使用final修飾的變數是因為Java的實現方式,一個匿名內部類(AIC)可以使用方法變數是通過拷貝一份變數作為內部類的私有變數。內部類並不是真正的使用方法的區域性變數,而是一份拷貝。在這點上,如果原來的值和拷貝的值發生變化,很顯然會導致不好的事情發生,可能會導致不可預期的資料同步問題發生。為了避免這型別的問題發生,Java要求你將方法變數用final修飾,這保證了內部類拷貝的方法變數總是與實際的變數一致。

tips:java7需要顯示宣告final變數,java8會自動為你新增final關鍵字修飾