溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JavaString對(duì)象是什么

發(fā)布時(shí)間:2021-09-13 17:10:00 來源:億速云 閱讀:128 作者:柒染 欄目:MySQL數(shù)據(jù)庫

這篇文章將為大家詳細(xì)講解有關(guān)JavaString對(duì)象是什么,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

Java String 對(duì)象,你真的了解了嗎? 

String對(duì)象是 Java 中使用最頻繁的對(duì)象之一,所以 Java 公司也在不斷的對(duì)String對(duì)象的實(shí)現(xiàn)進(jìn)行優(yōu)化,以便提升String對(duì)象的性能,看下面這張圖,一起了解一下String對(duì)象的優(yōu)化過程。

  在 Java6 以及之前的版本中String對(duì)象是對(duì) char 數(shù)組進(jìn)行了封裝實(shí)現(xiàn)的對(duì)象,主要有四個(gè)成員變量:char 數(shù)組、偏移量 offset、字符數(shù)量 count、哈希值 hash。String對(duì)象是通過 offset 和 count 兩個(gè)屬性來定位 char[] 數(shù)組,獲取字符串。這么做可以高效、快速地共享數(shù)組對(duì)象,同時(shí)節(jié)省內(nèi)存空間,但這種方式很有可能會(huì)導(dǎo)致內(nèi)存泄漏。2. 從 Java7 版本開始到 Java8 版本從 Java7 版本開始,Java 對(duì)String類做了一些改變。String類中不再有 offset 和 count 兩個(gè)變量了。這樣的好處是String對(duì)象占用的內(nèi)存稍微少了些,同時(shí) String.substring 方法也不再共享 char[],從而解決了使用該方法可能導(dǎo)致的內(nèi)存泄漏問題。3. 從 Java9 版本開始將 char[] 數(shù)組改為了 byte[] 數(shù)組,為什么需要這樣做呢?我們知道 char 是兩個(gè)字節(jié),如果用來存一個(gè)字節(jié)的字符有點(diǎn)浪費(fèi),為了節(jié)約空間,Java 公司就改成了一個(gè)字節(jié)的byte來存儲(chǔ)字符串。這樣在存儲(chǔ)一個(gè)字節(jié)的字符是就避免了浪費(fèi)。在 Java9 維護(hù)了一個(gè)新的屬性 coder,它是編碼格式的標(biāo)識(shí),在計(jì)算字符串長度或者調(diào)用 indexOf() 函數(shù)時(shí),需要根據(jù)這個(gè)字段,判斷如何計(jì)算字符串長度。coder 屬性默認(rèn)有 0 和 1 兩個(gè)值, 0 代表Latin-1(單字節(jié)編碼),1 代表 UTF-16 編碼。如果 String判斷字符串只包含了 Latin-1,則 coder 屬性值為 0 ,反之則為 1。

  通過字符串常量的方式String str= "pingtouge"的形式,使用這種形式創(chuàng)建字符串時(shí), JVM 會(huì)在字符串常量池中先檢查是否存在該對(duì)象,如果存在,返回該對(duì)象的引用地址,如果不存在,則在字符串常量池中創(chuàng)建該字符串對(duì)象并且返回引用。使用這種方式創(chuàng)建的好處是:避免了相同值的字符串重復(fù)創(chuàng)建,節(jié)約了內(nèi)存。2、String()構(gòu)造函數(shù)的方式String str = new String("pingtouge")的形式,使用這種方式創(chuàng)建字符串對(duì)象過程就比較復(fù)雜,分成兩個(gè)階段,首先在編譯時(shí),字符串pingtouge會(huì)被加入到常量結(jié)構(gòu)中,類加載時(shí)候就會(huì)在常量池中創(chuàng)建該字符串。然后就是在調(diào)用new()時(shí),JVM 將會(huì)調(diào)用String的構(gòu)造函數(shù),同時(shí)引用常量池中的pingtouge字符串,在堆內(nèi)存中創(chuàng)建一個(gè)String對(duì)象并且返回堆中的引用地址。了解了String對(duì)象兩種創(chuàng)建方式,我們來分析一下下面這段代碼,加深我們對(duì)這兩種方式的理解,下面這段代碼片中,str是否等于str1呢?

  我們逐一來分析這幾行代碼,首先從String str = "pingtouge"開始,這里使用了字符串常量的方式創(chuàng)建字符串對(duì)象,在創(chuàng)建pingtouge字符串對(duì)象時(shí),JVM會(huì)去常量池中查找是否存在該字符串,這里的答案肯定是沒有的,所以JVM將會(huì)在常量池中創(chuàng)建該字符串對(duì)象并且返回對(duì)象的地址引用,所以str指向的是pingtouge字符串對(duì)象在常量池中的地址引用。

  然后是String str1 = new String("pingtouge")這行代碼,這里使用的是構(gòu)造函數(shù)的方式創(chuàng)建字符串對(duì)象,根據(jù)我們上面對(duì)構(gòu)造函數(shù)方式創(chuàng)建字符串對(duì)象的理解,str1得到的應(yīng)該是堆中pingtouge字符串的引用地址。由于str指向的是pingtouge字符串對(duì)象在常量池中的地址引用而str1指向的是堆中pingtouge字符串的引用地址,所以str肯定不等于str1。

  從我們知道String對(duì)象的那一刻起,我想大家都知道了String對(duì)象是不可變的。那它不可變是怎么做到的呢?Java 這么做能帶來哪些好處?我們一起來簡單的探討一下,先來看看String 對(duì)象的一段源碼:

  從這段源碼中可以看出,String類用了 final 修飾符,我們知道當(dāng)一個(gè)類被 final 修飾時(shí),表明這個(gè)類不能被繼承,所以String類不能被繼承。這是String不可變的第一點(diǎn)

  再往下看,用來存儲(chǔ)字符串的char value[]數(shù)組被private 和final修飾,我們知道對(duì)于一個(gè)被final的基本數(shù)據(jù)類型的變量,則其數(shù)值一旦在初始化之后便不能更改。這是String不可變的第二點(diǎn)。Java 公司為什么要將String設(shè)置成不可變的,主要從以下三方面考慮:1、保證 String 對(duì)象的安全性。假設(shè) String 對(duì)象是可變的,那么 String 對(duì)象將可能被惡意修改。2、保證 hash 屬性值不會(huì)頻繁變更,確保了唯一性,使得類似 HashMap 容器才能實(shí)現(xiàn)相應(yīng)的 key-value 緩存功能。3、可以實(shí)現(xiàn)字符串常量池

關(guān)于JavaString對(duì)象是什么就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI