final修飾符是JAVA中比較簡單的一個修飾符,很多人通過書本就可以熟練掌握,但我學的時候,雖然感覺會用了,但是並不是十分理解這個修飾符,所以我找了相關資料,把我的個人理解分享給大家~~
final書本定義:
1.final可以修飾變量,被final修飾的變量被賦初值后,不能對它重新賦值
2.final可以修飾變量,被final修飾的方法被重寫
3.final可以修飾類,被final修飾的類不能派生子類
總的來說,就是值不能改,方法不能重寫,類不能繼承,就相當於是終結版。。。。
一、final修飾的變量
被final修飾的實例變量必須顯示地賦初值,且只能以下三種方式:
1、定義時初始化
2、在非靜態初始化塊中為final實例變量指定初始值
3、在構造器中指定初始值
對於局部變量,則必須賦初值,且賦值后不能再改變~
給個例子:
二、宏變量
對於一個final變量,不管它時類變量、實例變量、還是局部變量,只要定義該變量時使用了final修飾,並在定義該final類變量時指定了初始值,而且該初始值可以在編譯時被確定下來,那么這個final變量實質上已經不是變量,相當於一個恆量或者是直接量。
那么,何為宏變量?顧名思義,我覺得,所謂宏變量,其實就是恆變量。當定義final變量時就為該變量指定了初始值,而且該初始值在編譯時就已經確定下來,那么這個final變量本質上就是一個“宏變量”,編譯器會把程序中所有用到該變量的地方直接替換成該變量的值。
下面舉一個經典例子,相信大家都遇到過:
大家先看test測試單元,這是沒有添加final修飾符的,那么測試結果為 true/false。str1是一個普通字符串,str2是兩個字符串直接量進行連接,由於編譯器可以在編譯階段就確定s2的值”JAVAEE“,所以系統會讓s2直接指向字符串池中緩存中的”JAVAEE"字符串,所以str1==str2,返回結果為true。而對於str5而言,它的值由str3和str4連接得到,但是不是由兩個直接量連接,因此編譯器不會執行“宏替換”,因此編譯器無法在編譯時確定str5的值,不會讓str5指向字符串池中緩存中的“JAVAEE”,所以輸出false.
大家再來看test2測試單元,只要給str3和str4添加final修飾符,將其變成宏變量,則編譯器就能確定str5的值,從而輸出true.
PS:對於final實例變量而言,如果要將其變為“宏變量",則必須在定義該變量時就賦初值,否則無效,下面給個例子:
三、final方法不能被重寫
上面程序Base類中,用final定義父類info方法,但是被final定義的方法是不能重寫的,所以exe7中的info的方法並不是重寫Base中的方法,只是子類中的一個普通方法,如果要檢查子類中的方法是不是重寫父類中的方法,可以給方法強制添加@Override注釋,如果方法報錯,則不是重寫方法。
四、內部類中的局部變量
注意:如果程序要在內部類中使用局部變量,那么這個局部變量必須使用final修飾!
PS:此處說的內部類指的是局部內部類,因為只有局部內部類(包括匿名內部類)才可以訪問局部變量,普通靜態內部類、非靜態內部類不可能訪問方法體重的局部變量。