String類為什麼是final的
一、理解final
望文生義,final意為“最終的,最後的”,我理解為“不能被改變的”,它可以修飾類、變數和方法。
所以我是否可以理解為被它所修飾的類、變數和方法都不能被改變呢?答案是”是“,因為有以下約束條件的存在:
1、final修飾類
被final修飾的類不能被繼承,即它不能擁有自己的子類,否在會在編譯期間報錯。且看下面的例子:
第一步:建立一個用final修飾的父類Father
第二步:建立一個子類Son繼承Father
如圖所示,我們看到了報警資訊,點進去一看,如下圖所示:
意思就是類Son不能繼承被final修飾的類Father,上面的結論得以印證。
2、final修飾方法
被final修飾的方法不能被重寫,但是:
重寫的前提是子類可以從父類中繼承此方法,所以當父類中被final修飾的方法的訪問許可權為private時,子類中就可以重寫該方法了。
詳情且看下面的例項:
(一)父類中的方法控制權限為public
第一步:在Father類中建立一個方法,並用final修飾
第二步:用類Son繼承類Father並重寫work方法
可以看到當子類重寫父類中用final修飾的方法時,報錯了,報錯資訊如下:
即子類不能重寫父類中被final修飾的方法
下面看另一種情況
(二)父類中的方法控制權限為private
第一步:在Father類中建立一個方法,並用final修飾
第二步:用類Son繼承類Father並重寫work方法
可以看到程式沒有報錯,黃色下劃線的warning如下所示:
意為該方法沒有被使用,而當我把方法的控制權限改為public並且不用final修飾時,一切繼承和重寫都是正常的,如下圖所示:
由此,第二條結論也得以印證。
3、final修飾變數
final修飾的變數,無論是類屬性、物件屬性、形參還是區域性變數,都需要進行初始化操作。
(1)修飾變數
可以看到被final修飾的變數報錯了,報錯資訊如下:
意為被final修飾的欄位language沒有被初始化,所以當變數被final修飾時要賦值初始化,如下:
(2)修飾類屬性
類屬性可以理解為一個將一個類作為另一個類的屬性
第一步:先建立一個特徵類
第二步:將特徵類Feature設定為Son類的屬性,並用final修飾
同樣當類屬性用final修飾時報錯了,報錯資訊如下:
同樣,報錯資訊為沒有進行對final修飾的類進行初始化,下面看一下不用final修飾時是否報錯:
很明顯,答案是沒有,那再來看一下當初始化Feature類後又會是怎樣的?
可以看到,初始化用fina修飾的屬性類後並沒有報錯,上面的結論也得以印證了!
二、解答問題
結合以上基礎知識,我們來分析一下為什麼String類是final的?
首先來看一個例子:
上面這個例子,是讓一個普通類繼承String類,結果發現報錯了,錯誤資訊如下:
即類String1不能是final類String的子類,這裡已經很明顯地看出String類是final的,但是到底是為了什麼呢?先給出答案吧:
主要是為了”安全性“和”效率“的緣故,因為:
1、由於String類不能被繼承,所以就不會沒修改,這就避免了因為繼承引起的安全隱患;
2、String類在程式中出現的頻率比較高,如果為了避免安全隱患,在它每次出現時都用final來修飾,這無疑會降低程式的執行效率,所以乾脆直接將其設為final一提高效率;
下面是我在其他人的部落格中發現的一個很有趣也很有價值的答案,截圖拿來參考一下這位高人的解釋: