java中String類爲什麼要設計成final

這是個很有趣的問題,String設計成final類型,不能被繼承、不能被重寫,簡言之String是不可變的。問題在於爲什麼不可變呢?這主要是性能與安全性的考慮。String是JVM中使用頻率非常高的數據類型,涉及很多底層操作,因此SUN公司的工程師在設計String時,很小心的把整個String設置成final禁止繼承,避免被其他人繼承後破壞。另外一方面String作爲高頻使用數據類型,SUN對String的內存分配做了很多優化,比如字符串常量池,就是基於String的不可變性來實現的。

String內存分配機制

當在class文件被JVM裝載到方法區後,JVM會創建一個常量池,常量池用於存放該類型所用到直接常量(String,Integer和 Floating point常量)和對其他類型,字段和方法的符號引用。對於String類型,當執行字符串初始化時,JVM會先在常量池檢查是否存在字符串對象,如果存在則將字符串變量引用指向已經存在的對象。

創建賦值過程分析:在class文件被JVM裝載到內存中,JVM會創建一塊String Pool(String緩衝池)。當執行String s = “abc”;時,JVM首先在String Pool中查看是否存在字符串對象“abc”(如何查看呢?用equals()方法判斷),如果已存在該對象,則不用創建新的字符串對象“abc”,而直接使用String Pool中已存在的對象“abc”,然後將引用指向該對象;如果不存在該對象,則先在String Pool中創建一個新的字符串對象“abc”,然後將引用指向String Pool中創建的新對象。當要對變量進行賦值,則會重新創建一個字符串對象然後把這個對象的引用導向變量。

從這裏可以看出,常量池中一個字符串對象會指向多個變量的,如果String可變,那麼就會導致多個變量的值同時發生變動,這顯然不是我們所希望的。當然你可以說這是JVM的原因,那麼如果你設計的String是可變的,你必須同時兼顧JVM創建字符串,字符串變動的一系列流程。即使這是可行的,那麼必然會導致String對象的增多,JVM內存使用率的降低。對於一個使用頻率很高對類型,這樣的影響我們可能會無法接受。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章