1. 程式人生 > >java中內部類訪問區域性變數為什麼要定義區域性變數為final

java中內部類訪問區域性變數為什麼要定義區域性變數為final

因為方法內定義的變數是區域性變數,離開該方法,變數就失去了作用,也就會自動被消除,而內部類卻不會離開它所在方法就失去作用,它有更廣的生命週期,下面通過一個例項加以說明:
如例中所示,在外部類Outer中聲明瞭一個內部類TimerPrint,這個類中的方法引用了方法start中的一個區域性變數testTxt
邏輯上:因為該內部類出現在一個方法的內部,但實際編譯時,內部類編譯為Outer$1TimerPrint.class,這說明,外部類的這個方法和內部類是處於同一級別的。換句話說是非final變數和內部類的生命週期不一樣!start被呼叫後,非final變數也會隨之消失,就會出現內部類引用非法!
實際做法:
java編譯器
的行為是這樣的(前提條件是該變數在內部類中被引用): 若定義為final,則java編譯器則會在內部類TimerPrint內生成一個外部變數的拷貝,而且可以既可以保證內部類可以引用外部屬性,又能保證值的唯一性。 若不定義為final,則 無法通過編譯!( jdk1.6測試過)。 因為編譯器不會給非final變數進行拷貝,那麼 內部類引用的變數就是非法的! 下面看經過編譯以後的位元組碼: 外部類編譯後的位元組碼: 內部類編譯後的位元組碼: 如果外部類中的變數d沒有被內部類引用,則final為可選的,而且 java編譯器將不做特殊處理!! 加一個引數d 並且把它定義為非final型別,編譯以後檔案如下: 編譯後的外部類class: 編譯後的內部類class: 由上可以看出,在方法內部定義內部類時,內部類如果呼叫了方法內的變數,則該變數必須被final修飾,否則就會因為在呼叫內部類時因為找不到所用的變數而報錯!