Java中為什麼String類被定義成final

首先看下final關鍵字修飾類的作用:被final修飾的類不可被繼承,由此,這個問題就變成了,

為什麼官方不允許繼承String

我們先看下官方對String類的註釋的一點說明

<code>Strings are constant; their values cannot be changed after they are created/<code>

大意為:字符串是常量,他們的值在被創建以後不能夠被修改。

說到這裡,我們先看下最常見的字符串對象的創建方式

<code>String str1 = "abc";
String str2 = new String("abc")
//讀者可以思考下以上兩種方式的卻別/<code>

上面兩種創建String對象的區別在於:

  • 前者不會在堆中生成實例對象,而會在常量池中產生一個字符串常量
  • 後者會在堆成生成一個String類型的實例,不會在常量池中產生字符串常量


Java中為什麼String類被定義成final

從圖中也能看出兩種方式的區別

從上圖中可以直觀的看出同樣是創建String,前者比後者更節省內存,因為使用了常量池技術,而實現常量池,就必須保證字符串不可變。假設有兩個String對象分別指向常量池中的同一個字符串“abc”,如果第三個字符串改變了這個常量池的字符串,那勢必會導致前兩個String對象的值發生變化,進而導致程序異常。

讀者可以思考一個問題:假設讓你實現一個常量池,字符串可變,能實現麼?

講到這裡,String類被定義成final的第一個原因大家應該都比較清楚了,我們繼續分析,在JDK當中,不僅僅String類被定義成final,Integer、Long、Double等基本的包裝類型都被定義成final,為什麼這些基礎的類型都被定義成final了呢,這裡我認為最根本的一個原因在於:安全

JVM虛擬機無論再怎麼跨平臺,講到底,還是基於在操作系統上實現的,這些所謂String對象,Integer對象在堆內存當中,對於操作系統而言也無非是一塊內存數據,如果有一些開發者繼承String對象,通過內部方法調用獲取到其他String對象的信息,那會導致信息洩露,舉個例子,你通過String在內存中存儲了密碼,我繼承一個String類,獲取你的密碼,那這樣就會有極大的安全隱患。

總結下,為什麼String類被定義成final?

  1. 為了實現常量池,節省內存
  2. 為了安全


如果大家有不同意見,歡迎評論


分享到:


相關文章: