final修飾符的使用:
1.final能夠修飾變量,被final修飾的變量,被初始值的時候,不能再對其從新賦值;
1>:final 修飾實例變量:final 修飾實例變量必須在聲明時顯示賦值,能夠在定義變量、非靜態初始化塊
、構造器中爲final類型值賦值:java
example: public class FinalTest{\ //定義時賦值 final String va1="asd"; final String va2; final String var3; //非靜態初始化塊 { va2="aasdasd"; } //在構造器賦值 public FinalTest(){ var3="ASdsa"; } }
須要注意的是:通過編譯器的處理,這三種方式都會被抽取到構造器中賦初值
實質上:程序員只能在構造器裏邊對Final值賦值
2>:final 能夠修飾類變量:final類變量能夠在定義時、靜態初始化塊中進行賦值程序員
example: class FinalClassStoreTest{ final static String Name="asdas"; static{ final static Stirng Sec__Name="asdasd"; } }
實質上,final類對象在編譯器的做用下都是在static靜態初始化塊進行初始化賦值的,而且在以後
不可改變
3>:final==》宏變量==》宏代替
實例變量、類變量、局部變量在被final修飾以後本質上已經再也不是一個變量了,而是變成了 一個常量
當定義final變量的時候時指定了初始值,並且該值就今後肯定了下來,那麼這個final值就是一個"宏變量"
編譯器會把全部程序中全部用到該變量的地方直接替換成該變量的值
除了在給final類型值直接賦值外,若是被賦的表達式沒有訪問變量、調用方法,
而只是基本的算術運算表達式或字符串鏈接運算,
example:閉包
String va_1=」asda「 final String va_2 =」asdas「+ va_1; //不是宏變量 final String va_3="asdas"+"asda"; //是宏變量 final String va_4="asdas"+String.valueof("asda"); //不是宏變量 boolean(va_4==va_3) //false
2.final方法不能重寫:
1》.若是父類的方法被private修飾,不能被子類繼承到,全部就實現了假重寫;使用
@Override 會報錯;
@Override能夠檢測該方法是否被重寫,若是沒有被重寫就編譯錯誤併發
example: class father{ final private void Display(){ //your code } } class son extends father{ //@Override 報錯,由於此時並無重寫Display方法 void Display(){ //your code } }
2>當父類和子類並不在同一個包裏邊時,而且父類中的某個方法沒有訪問修飾符修飾(只用了final修飾),
此時就能夠實現「假重寫」;
使用@Override時會報錯
3.若是程序須要在內部類中訪問局部變量時,那麼這個局部變量就必須使用Final符修飾:涉及到閉包(Closure)問題ide
Example: public class ClosureTest{ public static void main(){ final va=5; new Thread(new Ruunable(){ public void run(){ for(int i=0;i<10;i++) System.out.print("i"+va); //使用 try{ Thread.sleep(1000); }catch(e){ e.printStack(); } } }).start(); }}
當程序運行時,mian()線程很早就執行完畢,而當前併發的線程卻並無中止,原本va時屬於main()做用域
的變量,如今被其餘做用域所用,內部類擴大了變量的做用域,防止擴大局部變量的做用域,對變量的修改進而引發混亂
,因此當內部類引用局部變量時,局部變量必須修飾爲Finalspa