Cannot refer to a non-final variable file inside an inner class defined in a different method(2012-09-17 12:36:19)
Cannot refer to a non-final variable file inside an inner class
defined in a different method
如果定義一個(gè)局部?jī)?nèi)部類,并且局部?jī)?nèi)部類使用了一個(gè)在其外部定義的對(duì)象,為什么編譯器會(huì)要求其參數(shù)引用是final呢? 注意:局部?jī)?nèi)部類,包括匿名內(nèi)部類。 原因如下: abstract class ABSClass{ public abstract void print(); } public class Test2{ public static void test(final String s){//一旦參數(shù)在匿名類內(nèi)部使用,則必須是final ABSClass c=new ABSClass(){ public void print(){ System.out.println(s); } }; c.print(); } public static void main(String[] args){ test("Hello World!"); } } JVM中每個(gè)進(jìn)程都會(huì)有多個(gè)根,每個(gè)static變量,方法參數(shù),局部變量,當(dāng)然這都是指引用類型.基礎(chǔ)類型是不能作為根的,根其實(shí)就是一個(gè)存儲(chǔ)地址.垃圾回收器在工作時(shí)先從根開(kāi)始遍歷它引用的對(duì)象并標(biāo)記它們,如此遞歸到最末梢,所有根都遍歷后,沒(méi)有被標(biāo)記到的對(duì)象說(shuō)明沒(méi)有被引用,那么就是可以被回收的對(duì)象(有些對(duì)象有finalized方法,雖然沒(méi)有引用,但JVM中有一個(gè)專門(mén)的隊(duì)列引用它們直到finalized方法被執(zhí)行后才從該隊(duì)列中移除成為真正沒(méi)有引用的對(duì)象,可以回收,這個(gè)與本主題討論的無(wú)關(guān),包括代的劃分等以后再說(shuō)明).這看起來(lái)很好但是在內(nèi)部類的回調(diào)方法中,s既不可能是靜態(tài)變量,也不是方法中的臨時(shí)變量,也不是方法參數(shù),它不可能作為根,在內(nèi)部類中也沒(méi)有變量引用它,它的根在內(nèi)部類外部的那個(gè)方法中,如果這時(shí)外面變量s重指向其它對(duì)象,則回調(diào)方法中的這個(gè)對(duì)象s就失去了引用,可能被回收,而由于內(nèi)部類回調(diào)方法大多數(shù)在其它線程中執(zhí)行,可能還要在回收后還會(huì)繼續(xù)訪問(wèn)它.這將是什么結(jié)果?而使用final修飾符不僅會(huì)保持對(duì)象的引用不會(huì)改變,而且編譯器還會(huì)持續(xù)維護(hù)這個(gè)對(duì)象在回調(diào)方法中的生命周期.所以這才是final變量和final參數(shù)的根本意義. |
|
來(lái)自: 昵稱32218474 > 《java》