A. java內部類引用外部類中的局部變數為何必須是final問題解析
今天編寫一個多線程程序,發現在方法內定義內部類時,如果內部類調用了方法中的變數,那麼該變數必須申明為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修飾,否則就會因為在調用內部類時因為找不到所用的變數而報錯!望採納,謝謝。
B. java里final是什麼意思
final可以理解為最終的,例如在定義變數的時候加入final修飾,則表示這個變數只有在定義的時候初始化一次,以後不能再做初始化操作
C. java局部內部類與方法里final變數的關系
被final修飾的變數叫做常量,不被修飾的就是局部變數
局部變數在所處的方法執行結束後就已經死亡了,不存在了,但是局部內部類對象還可能一直存在(只要有人還引用該對象),這時就會出現了一個悲劇的結果,局部內部類對象訪問一個已不存在的局部變數。所以,在局部內部類中只能訪問被final修飾的變數,也就是常量.
他們倆硬要說什麼關系,那就是在局部內部類中只能訪問final常量,
D. 在Java中,final修飾符要如何使用
final,字面上的意思是「最後的,最終的」,在Java中表示同樣的含義。
final可以用來修飾變數、方法和類。
1.final修飾類
final修飾類時表示此類是「最後的、最終的」,即不能被繼承,不能擁有自己的子類。
如果試圖對一個已經用final修飾的類進行集成,則會在編譯期間發生錯誤。
2.final修飾方法
final修飾方法表示此方法已經是「最後的、最終的」含義,即此方法不能被重寫,但是可以被重載。PS:重寫的前提是子類可以繼承父類的方法,如果父類中final修飾的方法同時設置許可權為private,則會導致子類不能繼承此方法。但是,可以在子類中重新定義相同方法名和參數的方法,此時不會產生重寫與final的矛盾。而是在子類中重新定義了新的方法。因為父類中及被private又被final修飾的那個方法根本沒有被繼承,子類在重新定義這個同名同參數方法時不會發生編譯錯誤。
3.final修飾變數
final修飾的變數表示此變數是「最後的、最終的」。一旦定義了final變數並且在為其顯示初始化後,final修飾的變數值不可被改變。
注意Attention:
1、final修飾的變數,無論是類屬性、對象屬性、形參還是局部變數,這些變數都需要程序員顯示初始化,系統不會對final成員邊來那個進行隱式初始化。
final修飾局部變數,與為被final修飾的變數一樣,都需要顯示初始化。即局部變數都需要顯示初始化。
對一般的類屬性和對象屬性而言,首先都是先進行默認初始化,然後在對有顯示賦值的變數進行顯示初始化。
2、Java規定final修飾的類屬性和變數熟悉感必須要進行顯示初始化賦值。
3、無論是度與基本數據類型還是引用數據類型,final修飾的變數都是首次顯示初始化後就不能修改的。對於final修飾的基本數據類型,由於在編譯時就能確定該變數的至,於是吧該變數當做常量來處理。(常量命名規則:多個有意義的單詞連接是,所有字元大寫,單詞之間用下劃線分割)。對於final修飾的是引用數據類型,由於無法在編譯是獲得值,只能在運行時獲得值。引用變數指向的是實際的對象,但是存儲的是所指向對象的地址,因此,氣質不能修改以為著其所指向的對象不能修改,即指向哪一個只能一直指向他,不能指向別的對象,但是可以修改這個對象內的屬性。
E. 為什麼Java匿名內部類的方法中用到的局部變數都必須定義為final
保證局部變數在匿名內部類內外都不會被修改。
因為匿名內部類內部,實際上是復制了一份局部變數,然後在匿名內部類中使用。如果不設置為final,局部變數在外部被修改,會導致與匿名內部類之內的副本不一致,邏輯上說不通。所以Java虛擬機這么設計,強制設置局部變數為final,語義上保持一致性。
F. java中final,finally和finalize的區別
final修飾符(關鍵字)類聲明final意味著能再派新類能作父類繼承變數或聲明final保證使用改變聲明final變數必須聲明給定初值引用能讀取修改聲明final同能使用能重載 finally異處理提供 finally 塊執行任何清除操作finally則管否發異finally語句都執行 finalize名Java 技術允許使用 finalize() 垃圾收集器象內存清除前做必要清理工作finalize() 垃圾收集器刪除象前調用 Object 類定義所類都繼承類覆蓋 finalize() 整理系統資源或者執行其清理工
G. java中內部類中訪問局部變數需要被聲明為最終類型(final)
一個方法中局部變數使用完之後就被釋放掉了.而final定義的就超過了這個外部方法中的生命周期...
H. java局部內部類 變數前加final關鍵字
java8 的新特性,這種情況的final可以省略不寫。
雖然可以省略final,但是其實還是具有final的語義 ,不要試圖修改,否則報錯。
實際寫代碼時,加上final是較好的習慣。
參考代碼
classOuter{
voidm1(){
//局部變數
intage=10;//這個為啥不加final關鍵字也行
classInner{
voidm2(){
System.out.println(age++);//修改age,就會報錯提示你必須是final的
}
}
Inneri=newInner();
i.m2();
}
publicstaticvoidmain(String[]args){
Outero=newOuter();
o.m1();//10
}
}
I. Java中final修飾符可以分別用在什麼地方表示什麼意義
1,修飾類
當用final修飾一個類時,表明這個類不能被繼承。也就是說,如果一個類你永遠不會讓他被繼承,就可以用final進行修飾。final類中的成員變數可以根據需要設為final,但是要注意final類中的所有成員方法都會被隱式地指定為final方法。
在使用final修飾類的時候,要注意謹慎選擇,除非這個類真的在以後不會用來繼承或者出於安全的考慮,盡量不要將類設計為final類。
2,修飾方法
被final修飾的方法將不能被子類覆蓋,主要用於1,把方法鎖定,以防任何繼承類修改它的含。2,在早期的Java實現版本中,會將final方法轉為內嵌調用,所以效率能夠提升
3,修飾變數
對於一個final變數,如果是基本數據類型的變數,則其數值一旦在初始化之後便不能更改;如果是引用類型的變數,則在對其初始化之後便不能再讓其指向另一個對象。
當用final作用於類的成員變數時,成員變數(注意是類的成員變數,局部變數只需要保證在使用之前被初始化賦值即可)必須在定義時或者構造器中進行初始化賦值,而且final變數一旦被初始化賦值之後,就不能再被賦值了。