帶你一文深入認識Java?String類
前言
String 類在Java中是很常用的類,很重要的類,在后續(xù)的學習中經(jīng)常會用到,是后續(xù)學習的基礎(chǔ)
一、認識String
1.JDK中的String
首先我們看看JDK中的String類源碼,它實現(xiàn)了很多接口,可以看到String類被final修飾了,這就說明String類不可以被繼承,String不存在子類,這樣所有使用JDK的人,用到的String類都是同一個,如果String允許被繼承,每個人都可以對String進行擴展,每個人使用的String都不是同一個版本,兩個不同的人使用相同的方法,表現(xiàn)出不同的結(jié)果,這就導致代碼沒辦法進行開發(fā)了
繼承和方法覆寫在帶來靈活性的同時,也會帶來很多子類行為不一致的問題
2.創(chuàng)建字符串的四種方式
方式一:直接賦值(常用)
String str = " hello word "
方式二:通過構(gòu)造方法產(chǎn)生對象
String str1 = new String(" hello word ");
方式三:通過字符數(shù)組產(chǎn)生對象
char[] data = new char[]{‘a’ , ‘b’ ,‘c’};
方式四:通過String的靜態(tài)方法valueOf(任意數(shù)據(jù)類型) = >轉(zhuǎn)為字符串(常用)
String str2 = String.valueOf(10);
3.字符串的字面量
字面量:直接寫出來的數(shù)值叫做字面量
10 – > int字面量
10.1 --> double字面量
true --> boolean字面量
" abc " – > String字面量
字符串的字面量其實就是一個字符串對象
String str = “hello word”;
String str2 = str;
此時這既是一個字符串的字面量,也是字符串的對象,為了方便理解,畫個圖,此時是為了方便理解我們暫時先認為它儲存在堆上,其實實在方法區(qū)中存放
此時讓str2 = “Hello”;此時對str的輸出并沒有影響,因為被" "括起來的Hello也是一個字符串對象,說明此時在堆上新開辟了一塊空間,而此時str2保存的就是新對象的地址空間,對str沒有影響
4.字符串比較相等
所有的引用數(shù)據(jù)類型在比較是否相等時,使用equals方法比較,JDK的常用類,都已經(jīng)覆寫了equals方法,直接使用即可
引用數(shù)據(jù)類型使用 == 比較的是地址
下圖是兩個引用指向了同一塊地址空間,和字符串的常量池有關(guān)
下圖產(chǎn)生了兩個對象,兩塊地址空間,使用==返回的就是false
equals的比較大小是區(qū)分大小寫的比較
equalsIgnoreCase方法是不區(qū)分大小寫的比較
二、字符串的常量池
1.什么是字符串常量池
當使用直接賦值法產(chǎn)生字符串對象的時候,JVM會維護一個字符串的常量池,若該對象在堆中還不存,就產(chǎn)生一個字符串對象加入到字符串常量池中;當繼續(xù)使用直接賦值法產(chǎn)生字符串對象的時候,JVM發(fā)現(xiàn)該引用指向的內(nèi)容在常量池中已經(jīng)存在了,此時就不再新建字符串對象,而是直接復(fù)用已有的對象,這也是為什么上圖的三個引用指向的是同一塊地址
當?shù)谝淮萎a(chǎn)生對象的時候,常量池中還什么都沒有,就在常量池中產(chǎn)生一個字符串對象存入,當?shù)诙谌萎a(chǎn)生對象時,JVM發(fā)現(xiàn)常量池中已經(jīng)存在相同的內(nèi)容,就不再產(chǎn)生新的對象,直接指向和str1相同的地址空間
程序都是從右向左執(zhí)行的,此時第一行代碼的右邊就是一個字符串常量,也是一個字符串對象,所以先在常量池中開辟一塊空間,然后新建一個字符串對象存入,程序再往左執(zhí)行,遇到new關(guān)鍵字,此時新建一個對象存入堆中,然后str1 指向堆中的對象,在指向第二行第三行代碼時,發(fā)現(xiàn)常量池中已經(jīng)存在該對象,不再新建,遇到new關(guān)鍵字就新建對象,
內(nèi)存圖如下:
2.手工入池方法
String類提供的intern方法,這是一個本地方法:
調(diào)用intern方法會將當前字符串引用指向的對象保存到字符串常量池中,有兩種情況:
- 1.若當前常量池中已經(jīng)存在了該對象,則不再產(chǎn)生新的對象,返回常量池中的String對象
- 2.若當前常量池中不存在該對象,則將該對象入池,返回入池后的地址。
看一下下面這幾行代碼的輸出:
因為intern方法是有返回值的,此時str1只是調(diào)用了intern方法,并沒有接收返回值,所以str1還是指向堆中的對象,str2指向常量池中的對象,所以返回false;
只要接收一下調(diào)用intern方法的返回值,就會返回true;
此時就將str1指向的對象手動入池了,池中已有該對象,直接讓str1指向該對象
再看看下面這幾行代碼的輸出:
手動入池時,池中還沒有任何東西,直接移入常量池中
三、字符串的不可變性 1.為什么不可變
注意:所謂的字符串不可變,指的是字符串的內(nèi)容不可變,而不是字符串的引用不能變
這里的不可變指的是" hello " , " world " , " helloworld " , " !!! " , 以及拼接后的"helloworld!!!"這些已經(jīng)創(chuàng)建好的字符串對象,這些對象一旦聲明后就無法修改其內(nèi)容,但是引用是可以改變的,一會指向hello,一會指向helloworld,一會指向hello world?。?!,這都是可以的
字符串就是就是一個字符數(shù)組—> char[],字符串其實在字符數(shù)組中保存。字符串的內(nèi)容為什么不能改變?我們看看字符串的源碼就知道了。
我們可以看到String內(nèi)部的字符數(shù)組是被封裝起來的,String類的外部無法訪問到這個字符數(shù)組,更何談改變字符串的內(nèi)容
String str = " hello ";
2.如何修改字符串內(nèi)容
- 1.在運行時通過反射破壞value數(shù)組的封裝
- 2.更換使用StringBuilder或者StringBuffer類 - - 已經(jīng)不是一個類型了
- a.StringBuilder:線程不安全,性能較強
- b.StringBuffer:線程安全,性能較差
除此之外兩個類的用法完全相同
若需要頻繁的進行字符串的拼接,使用StringBuilder類的append方法,這里只產(chǎn)生了一個對象,一會變成hello,一會變成hello world
3.StringBuilder類的具體使用
StringBuilder類和String是兩個獨立的類,StringBuilder類就是為了解決字符串的拼接問題產(chǎn)生的
StringBuilder類和String類的相互轉(zhuǎn)換:
1.StringBuilder變?yōu)镾tring類調(diào)用toString方法即可
2.String類轉(zhuǎn)變?yōu)镾tringBuilder類,使用StringBuilder的構(gòu)造方法或者append方法
其他常用方法:
a.字符串的反轉(zhuǎn)操作,sb提供的reverse();
b.刪除指定范圍的數(shù)據(jù),delete(int start,int end);刪除從start開始,到end之前的所有內(nèi)容,左閉右開區(qū)間
c.插入操作,insert(int start,各種數(shù)據(jù)類型):從start索引位置開始插入,插入的起始索引為start
到此這篇關(guān)于帶你一文深入認識Java String類的文章就介紹到這了,更多相關(guān)Java String類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java中String類的常用方法總結(jié)
- Java?String類的理解及字符串常量池介紹
- Java中String類常用方法總結(jié)詳解
- Java基礎(chǔ)之String類使用與字符串比較
- Java中String類常用方法使用詳解
- Java String類常用方法梳理總結(jié)
- Java深入淺出講解String類常見方法
- Java詳細分析String類與StringBuffer和StringBuilder的使用方法
- Java?String類和StringBuffer類的區(qū)別介紹
- Java全面解析string類型的xml字符串
- Java中String類常用類型實例總結(jié)
- 深入剖析Java中String類的concat方法
- 詳解Java中String類的各種用法
- 一文帶你初識java中的String類
- Java String類的性質(zhì)與比較
- 關(guān)于Java中String類字符串的解析
- Java String類字符串的理解與認知
- Java-String類最全匯總(上篇)
相關(guān)文章
詳解Java并發(fā)工具類之CountDownLatch和CyclicBarrier
在JDK的并發(fā)包中,有幾個非常有用的并發(fā)工具類,它們分別是:CountDownLatch、CyclicBarrier、Semaphore和Exchanger,本文主要來講講其中CountDownLatch和CyclicBarrier的使用,感興趣的可以了解一下2023-06-06spring注入在有常量的情況下使用@AllArgsConstructor操作
這篇文章主要介紹了spring注入在有常量的情況下使用@AllArgsConstructor操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09Springsecurity Oauth2如何設(shè)置token的過期時間
如果用戶在指定的時間內(nèi)有操作就給token延長有限期,否則到期后自動過期,如何設(shè)置token的過期時間,本文就來詳細的介紹一下2021-08-08springboot項目組引入JMeter的實現(xiàn)步驟
本文主要介紹了springboot項目組引入JMeter的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09詳解SpringCloud Gateway之過濾器GatewayFilter
這篇文章主要介紹了詳解SpringCloud Gateway之過濾器GatewayFilter,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-10-10java實現(xiàn)騰訊ocr圖片識別接口調(diào)用
這篇文章主要為大家詳細介紹了java實現(xiàn)騰訊ocr圖片識別接口調(diào)用,拍車牌識別車牌號功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-11-11