ava String 物件,你真的瞭解了嗎?
Java String 物件,你真的瞭解了嗎?
分類: JavaScript2020-03-23 18:22:38
String物件是 Java 中使用最頻繁的物件之一,所以 Java 公司也在不斷的對String物件的實現進行最佳化,以便提升String物件的效能,看下面這張圖,一起了解一下String物件的最佳化過程。
1. 在 Java6 以及之前的版本中String物件是對 char 陣列進行了封裝實現的物件,主要有四個成員變數:char 陣列、偏移量 offset、字元數量 count、雜湊值 hash。String物件是透過 offset 和 count 兩個屬性來定位 char[] 陣列,獲取字串。這麼做可以高效、快速地共享陣列物件,同時節省記憶體空間,但這種方式很有可能會導致記憶體洩漏。2. 從 Java7 版本開始到 Java8 版本從 Java7 版本開始,Java 對String類做了一些改變。String類中不再有 offset 和 count 兩個變數了。這樣的好處是String物件佔用的記憶體稍微少了些,同時 String.substring 方法也不再共享 char[],從而解決了使用該方法可能導致的記憶體洩漏問題。3. 從 Java9 版本開始將 char[] 陣列改為了 byte[] 陣列,為什麼需要這樣做呢?我們知道 char 是兩個位元組,如果用來存一個位元組的字元有點浪費,為了節約空間,Java 公司就改成了一個位元組的byte來儲存字串。這樣在儲存一個位元組的字元是就避免了浪費。在 Java9 維護了一個新的屬性 coder,它是編碼格式的標識,在計算字串長度或者呼叫 indexOf() 函式時,需要根據這個欄位,判斷如何計算字串長度。coder 屬性預設有 0 和 1 兩個值, 0 代表Latin-1(單位元組編碼),1 代表 UTF-16 編碼。如果 String判斷字串只包含了 Latin-1,則 coder 屬性值為 0 ,反之則為 1。
1、透過字串常量的方式String str= "pingtouge"的形式,使用這種形式建立字串時, JVM 會在字串常量池中先檢查是否存在該物件,如果存在,返回該物件的引用地址,如果不存在,則在字串常量池中建立該字串物件並且返回引用。使用這種方式建立的好處是:避免了相同值的字串重複建立,節約了記憶體。2、String()建構函式的方式String str = new String("pingtouge")的形式,使用這種方式建立字串物件過程就比較複雜,分成兩個階段,首先在編譯時,字串pingtouge會被加入到常量結構中,類載入時候就會在常量池中建立該字串。然後就是在呼叫new()時,JVM 將會呼叫String的建構函式,同時引用常量池中的pingtouge字串,在堆記憶體中建立一個String物件並且返回堆中的引用地址。瞭解了String物件兩種建立方式,我們來分析一下下面這段程式碼,加深我們對這兩種方式的理解,下面這段程式碼片中,str是否等於str1呢?
我們逐一來分析這幾行程式碼,首先從String str = "pingtouge"開始,這裡使用了字串常量的方式建立字串物件,在建立pingtouge字串物件時,JVM會去常量池中查詢是否存在該字串,這裡的答案肯定是沒有的,所以JVM將會在常量池中建立該字串物件並且返回物件的地址引用,所以str指向的是pingtouge字串物件在常量池中的地址引用。
然後是String str1 = new String("pingtouge")這行程式碼,這裡使用的是建構函式的方式建立字串物件,根據我們上面對建構函式方式建立字串物件的理解,str1得到的應該是堆中pingtouge字串的引用地址。由於str指向的是pingtouge字串物件在常量池中的地址引用而str1指向的是堆中pingtouge字串的引用地址,所以str肯定不等於str1。
從我們知道String物件的那一刻起,我想大家都知道了String物件是不可變的。那它不可變是怎麼做到的呢?Java 這麼做能帶來哪些好處?我們一起來簡單的探討一下,先來看看String 物件的一段原始碼:
從這段原始碼中可以看出,String類用了 final 修飾符,我們知道當一個類被 final 修飾時,表明這個類不能被繼承,所以String類不能被繼承。這是String不可變的第一點
再往下看,用來儲存字串的char value[]陣列被private 和final修飾,我們知道對於一個被final的基本資料型別的變數,則其數值一旦在初始化之後便不能更改。這是String不可變的第二點。Java 公司為什麼要將String設定成不可變的,主要從以下三方面考慮:1、保證 String 物件的安全性。假設 String 物件是可變的,那麼 String 物件將可能被惡意修改。2、保證 hash 屬性值不會頻繁變更,確保了唯一性,使得類似 HashMap 容器才能實現相應的 key-value 快取功能。3、可以實現字串常量池
:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69971700/viewspace-2694394/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 每天都在用String,你真的瞭解嗎?
- HTTPS 你瞭解了嗎?HTTP
- Object物件你真理解了嗎?Object物件
- 谷歌官方元件Navigation你瞭解了嗎?谷歌元件Navigation
- 幽默圖:你瞭解了量子力學嗎?
- Java String 物件,你瞭解多少?Java物件
- 你真的瞭解RPC嗎?RPC
- 你真的瞭解@Async嗎?
- ViewStub你真的瞭解嗎View
- 你真的瞭解 Array 嗎?
- 你真的瞭解mongoose嗎?Go
- 你真的瞭解HTAP嗎
- 你真的瞭解URLEncode嗎?
- Javascript建立陣列的方式你瞭解了嗎JavaScript陣列
- 你真的瞭解前端路由嗎?前端路由
- JavaScript 你真的瞭解this指向嗎JavaScript
- 你真的瞭解過 ConcurrentHashMap 嗎?HashMap
- python是什麼?這些你都瞭解了嗎?Python
- 你真的瞭解js運算子嗎JS
- 你真的瞭解npm-scripts嗎?NPM
- 你真的瞭解 Cookie 和 Session 嗎CookieSession
- 高併發,你真的瞭解嗎?
- 你真的瞭解 sync.Once 嗎
- 你真的瞭解深度學習嗎?深度學習
- 你真的瞭解 Cookie 和 Session 嗎?CookieSession
- 你真的瞭解 Session 和 Cookie 嗎?SessionCookie
- 你真的瞭解JAVA中物件和類、this、super和static關鍵字嗎Java物件
- 你真的瞭解python嗎?這篇文章帶你快速瞭解!Python
- 你真的瞭解Event Loop(事件環)嗎?OOP事件
- 你真的瞭解 React 生命週期嗎React
- 你真的瞭解 OkHttp 快取控制嗎?HTTP快取
- 【極客思考】設計模式:你確定你真的理解了單例模式嗎?設計模式單例
- 真的懂Java的String嗎?Java
- CentOS停服遭替代,這些操作差異,你瞭解了嗎?CentOS
- 你真的瞭解 Unicode 和 UTF-8 嗎?Unicode
- 你真的瞭解響應式佈局嗎?
- 注意!JS的結構你真的瞭解嗎?JS
- Java併發(7)- 你真的瞭解 ReentrantReadWriteLock 嗎?Java