Java 關(guān)于String字符串原理上的問題
1、String 是最基本的數(shù)據(jù)類型嗎?
不是。
Java 中的基本數(shù)據(jù)類型只有 8 個(gè) :byte、short、int、long、float、double、char、boolean;除了基本類型,剩下的都是引用類型,Java 5 以后引入的枚舉類型也算是一種比較特殊的引用類型。
2、字符型常量和字符串常量的區(qū)別?
- 形式上: 字符常量是單引號(hào)引起的一個(gè)字符,字符串常量是雙引號(hào)引起的若干個(gè)字符;
- 含義上: 字符常量相當(dāng)于一個(gè)整型值( ASCII 值),可以參加表達(dá)式運(yùn)算;字符串常量代表一個(gè)地址值(該字符串在內(nèi)存中存放位置,相當(dāng)于對(duì)象;
- 占內(nèi)存大?。鹤址A恐徽?
2個(gè)字節(jié);字符串常量占若干個(gè)字節(jié)(至少一個(gè)字符結(jié)束標(biāo)志) (注意: char 在Java中占兩個(gè)字節(jié))。
3、什么是字符串常量池?
字符串常量池:jvm為了提升性能和減少內(nèi)存開銷,避免字符的重復(fù)創(chuàng)建,其維護(hù)了一塊特殊的內(nèi)存空間,即字符串常量池。當(dāng)需要使用字符串時(shí),先去字符串常量池中查看該字符串是否已經(jīng)存在,如果存在,則可以直接使用,如果不存在,初始化,并將該字符串放入字符串常量池中。
所處位置說明
- 在jdk6中,常量池的位置在永久代(方法區(qū))中,此時(shí)常量池中存儲(chǔ)的是對(duì)象。
- 在jdk7中,常量池的位置在堆中,此時(shí),常量池存儲(chǔ)的就是引用了。
- 在jdk8中,永久代(方法區(qū))被元空間取代了。
4、String str=new String(“aaa”)創(chuàng)建了幾個(gè)對(duì)象?
1個(gè)或者2個(gè)
- 第一種情況:字符串常量池中已經(jīng)有了
"aaa"字符串常量了,那么此時(shí)會(huì)在堆中通過new String()方法創(chuàng)建1個(gè)字符串對(duì)象。 - 第二種情況:那就是字符串常量池中沒有
"aaa"字符串常量了,此時(shí)會(huì)創(chuàng)建2個(gè)對(duì)象。首先"aaa"該表達(dá)式會(huì)查看字符串常量池中是否含有"aaa"常量,如果沒有的話,那么在字符串常量池中就會(huì)生成一個(gè)值為"aaa"的字符串常量,然后再在堆中通過new String()方法創(chuàng)建一個(gè)值為"aaa"的對(duì)象。
5、字符串的 intern 方法的執(zhí)行過程是怎樣的?
你學(xué) Java 的別這個(gè)高頻知識(shí)點(diǎn)都不知道呀,不知道的趕緊偷摸補(bǔ)一下。
在解析這個(gè)問題之前,我們先來做個(gè)題目:
public class Test {
public static void main(String[] args) {
String s = new String("2");
s.intern();
String s1 = "2";
System.out.println(s == s1);
String s3 = new String("3") + new String("3");
s3.intern();
String s4 = "33";
System.out.println(s3 == s4);
}
}
輸出結(jié)果
//jdk6
false
false
//jdk7
false
true
intern 方法在JDK1.6以前 和 JDK1.7以后有不同的處理:
- 在JDK1.6中,
intern的處理是 先判斷字符串常量是否在字符串常量池中,如果存在直接返回該常量,如果沒有找到,則將該字符串常量加入到字符串常量區(qū),也就是在字符串常量區(qū)建立該常量; - 在JDK1.7中,
intern的處理是 先判斷字符串常量是否在字符串常量池中,如果存在直接返回該常量,如果沒有找到,說明該字符串常量在堆中,則處理是把堆區(qū)該對(duì)象的引用加入到字符串常量池中,以后別人拿到的是該字符串常量的引用,實(shí)際存在堆中。
6、String,StringBuffer,StringBuilder 的區(qū)別是什么?
可變與不可變
String
// 源碼 private final char value[];
String 類中使用字符數(shù)組保存字符串,因?yàn)橛?“final” 修飾符,所以 String 對(duì)象是不可變的。對(duì)于已經(jīng)存在的 String 對(duì)象的修改都是重新創(chuàng)建一個(gè)新的對(duì)象,然后把新的值保存進(jìn)去。
StringBuffer 和 StringBuilder
// 源碼 char[] value;
StringBuffer 和 StringBuilder 都繼承自 AbstractStringBuilder 類,在 AbstractStringBuilder 中也是使用字符數(shù)組保存字符串,這兩種對(duì)象都是可變的。
是否多線程安全
String中的對(duì)象是不可變的,也就可以理解為常量,顯然線程安全。StringBuilder是非線程安全的。StringBuffer對(duì)方法加了同步鎖或者對(duì)調(diào)用的方法加了同步鎖,所以是線程安全的。
// StringBuffer 的追加操作
public synchronized StringBuffer append(StringBuffer sb) {
toStringCache = null;
super.append(sb);
return this;
}
性能
- 每次對(duì)
String類型進(jìn)行改變的時(shí)候,都會(huì)生成一個(gè)新的String對(duì)象,然后將指針指向新的String對(duì)象。 StringBuffer每次都會(huì)對(duì)StringBuffer對(duì)象本身進(jìn)行操作,而不是生成新的對(duì)象并改變對(duì)象引用。相同情況下使用StringBuilder相比使用StringBuffer僅能獲得 10%~15% 左右的性能提升,但卻要冒多線程不安全的風(fēng)險(xiǎn)。
7、String為什么要設(shè)計(jì)成不可變的?
- 便于實(shí)現(xiàn)字符串常量池。
- 使多線程安全
- 避免安全問題:在網(wǎng)絡(luò)連接和數(shù)據(jù)庫連接中字符串常常作為參數(shù),例如,網(wǎng)絡(luò)連接地址
URL,文件路徑path,反射機(jī)制所需要的String參數(shù)。其不可變性可以保證連接的安全性。如果字符串是可變的,黑客就有可能改變字符串指向?qū)ο蟮闹?,那么?huì)引起很嚴(yán)重的安全問題。 - 加快字符串處理速度:由于
String是不可變的,保證了hashcode的唯一性,于是在創(chuàng)建對(duì)象時(shí)其hashcode就可以放心的緩存了,不需要重新計(jì)算。這也就是Map喜歡將String作為Key的原因。
到此這篇關(guān)于Java 關(guān)于String字符串原理上的問題的文章就介紹到這了,更多相關(guān)Java String內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android開發(fā)中Socket通信的基本實(shí)現(xiàn)方法講解
這篇文章主要介紹了Android開發(fā)中Socket通信的基本實(shí)現(xiàn)方法講解,是安卓上移動(dòng)互聯(lián)網(wǎng)程序開發(fā)的基礎(chǔ),需要的朋友可以參考下2015-12-12
Java 仿天貓服裝商城系統(tǒng)的實(shí)現(xiàn)流程
讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SSM+jsp+mysql+maven實(shí)現(xiàn)一個(gè)仿天貓服裝商城系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平2021-11-11
spring配置定時(shí)任務(wù)的幾種方式總結(jié)
這篇文章主要介紹了spring配置定時(shí)任務(wù)的幾種方式總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
Spring實(shí)現(xiàn)IoC和DI的方法詳解
IoC全稱Inversion of Control (控制反轉(zhuǎn)) ,這里的控制其實(shí)是控制權(quán)的意思,可以理解為對(duì)象的獲取權(quán)力和方式發(fā)生了發(fā)轉(zhuǎn),DI依賴注?是?個(gè)過程,是指IoC容器在創(chuàng)建Bean時(shí), 去提供運(yùn)?時(shí)所依賴的資源,?資源指的就是對(duì)象,本文介紹了Spring實(shí)現(xiàn)IoC和DI的方法2024-08-08
MyBatis實(shí)現(xiàn)Mysql數(shù)據(jù)庫分庫分表操作和總結(jié)(推薦)
這篇文章主要介紹了MyBatis實(shí)現(xiàn)Mysql數(shù)據(jù)庫分庫分表操作和總結(jié),需要的朋友可以參考下2017-08-08
Springboot單體架構(gòu)http請(qǐng)求轉(zhuǎn)換https請(qǐng)求來支持微信小程序調(diào)用接口
這篇文章主要介紹了Springboot單體架構(gòu)http請(qǐng)求轉(zhuǎn)換https請(qǐng)求來支持微信小程序調(diào)用接口,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
Java內(nèi)存模型之重排序的相關(guān)知識(shí)總結(jié)
重排序是指編譯器和處理器為了優(yōu)化性能而對(duì)指令序列進(jìn)行重新排序的一種手段,文中詳細(xì)介紹了Java重排序的相關(guān)知識(shí),需要的朋友可以參考下2021-06-06
Java生產(chǎn)者消費(fèi)者的三種實(shí)現(xiàn)方式
這篇文章主要介紹了Java生產(chǎn)者消費(fèi)者的三種實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
Java實(shí)現(xiàn)一個(gè)小說采集程序的簡單實(shí)例
下面小編就為大家?guī)硪黄狫ava實(shí)現(xiàn)一個(gè)小說采集程序的簡單實(shí)例。小編覺得挺不錯(cuò)的, 現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-06-06

