真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

為什么Java中String類(lèi)設(shè)置完不能改

為什么Java中String類(lèi)設(shè)置完不能改?可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

創(chuàng)新互聯(lián)是專(zhuān)業(yè)的鶴崗網(wǎng)站建設(shè)公司,鶴崗接單;提供網(wǎng)站制作、成都網(wǎng)站建設(shè),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專(zhuān)業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行鶴崗網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專(zhuān)業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專(zhuān)業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!

String就是java等編程語(yǔ)言中的字符串,用雙引號(hào)引起來(lái)的幾個(gè)字符.如"Abc","一天".與字符不同的是它指的是一串字符或者一類(lèi)標(biāo)識(shí)符。String類(lèi)是不可變(final)的,對(duì)String類(lèi)的任何改變,都是返回一個(gè)新的String類(lèi)對(duì)象.這樣的話把String類(lèi)的引用傳遞給一個(gè)方法,該方法對(duì)String的任何改變,對(duì)原引用指向的對(duì)象沒(méi)有任何影響,這一點(diǎn)和基本數(shù)據(jù)類(lèi)型相似。

Java中String類(lèi)示例:

public final class String
    implements java.io.Serializable, Comparable, CharSequence {
    /** The value is used for character storage. */
    private final char value[];}

String類(lèi)的值是保存在value數(shù)組中的,并且是被private final修飾的

1、private修飾,表明外部的類(lèi)是訪問(wèn)不到value的,同時(shí)子類(lèi)也訪問(wèn)不到,當(dāng)然String類(lèi)不可能有子類(lèi),因?yàn)轭?lèi)被final修飾了
2、final修飾,表明value的引用是不會(huì)被改變的,而value只會(huì)在String的構(gòu)造函數(shù)中被初始化,而且并沒(méi)有其他方法可以修改value數(shù)組中的值,保證了value的引用和值都不會(huì)發(fā)生變化

所以我們說(shuō)String類(lèi)是不可變的。

而很多方法,如substring并不是在原來(lái)的String類(lèi)上進(jìn)行操作,而是生成了新的String類(lèi)

public String substring(int beginIndex) {
	if (beginIndex < 0) {
		throw new StringIndexOutOfBoundsException(beginIndex);
	}
	int subLen = value.length - beginIndex;
	if (subLen < 0) {
		throw new StringIndexOutOfBoundsException(subLen);
	}
	return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);}

字符串常量池

Java有8種基本數(shù)據(jù)類(lèi)型

整數(shù)類(lèi)型:byte,short,int,long。包裝類(lèi)型為Byte,Short,Integer,Long
浮點(diǎn)類(lèi)型:float、double。包裝類(lèi)型為Float,Double
字符類(lèi)型:char。包裝類(lèi)型為Character
布爾類(lèi)型:boolean。包裝類(lèi)型為Boolean

8種包裝類(lèi)型中除了Float,Double沒(méi)有實(shí)現(xiàn)常量池,剩下的都實(shí)現(xiàn)了,當(dāng)然都是通過(guò)享元模式實(shí)現(xiàn)的

String類(lèi)的常量池是在JVM層面實(shí)現(xiàn)的。

為什么要有常量池?

常量池是為了避免頻繁的創(chuàng)建和銷(xiāo)毀對(duì)象而影響系統(tǒng)性能,其實(shí)現(xiàn)了對(duì)象的共享。
例如字符串常量池,在編譯階段就把所有的字符串文字放到一個(gè)常量池中。

  • 節(jié)省內(nèi)存空間:常量池中所有相同的字符串常量被合并,只占用一個(gè)空間。

  • 節(jié)省運(yùn)行時(shí)間:比較字符串時(shí),== 比equals()快。對(duì)于兩個(gè)引用變量,只用==判斷引用是否相等,也就可以判斷實(shí)際值是否相等。

字符串常量池放在哪?

jdk1.7之前的不討論,從jdk1.7開(kāi)始,字符串常量池就開(kāi)始放在堆中,然后本文的所有內(nèi)容都是基于jdk1.8的

下面這個(gè)代碼還是經(jīng)常被問(wèn)到的

String str1 = "abc";
String str2 = "abc";
String str3 = new String("abc");
String str4 = new String("abc");
// trueSystem.out.println(str1 == str2);
// falseSystem.out.println(str1 == str3);
// falseSystem.out.println(str3 == str4);

內(nèi)存中的結(jié)構(gòu)如下
為什么Java中String類(lèi)設(shè)置完不能改
其中常量池中存的是引用

解釋一下上面代碼的輸出,Java中有2種創(chuàng)建字符串對(duì)象的方式

String str1 = "abc";
String str2 = "abc";
// trueSystem.out.println(str1 == str2);

采用字面值的方式創(chuàng)建一個(gè)字符串時(shí),JVM首先會(huì)去字符串池中查找是否存在"abc"這個(gè)對(duì)象

如果不存在,則在字符串池中創(chuàng)建"abc"這個(gè)對(duì)象,然后將池中"abc"這個(gè)對(duì)象的地址賦給str1,這樣str1會(huì)指向池中"abc"這個(gè)字符串對(duì)象

如果存在,則不創(chuàng)建任何對(duì)象,直接將池中"abc"這個(gè)對(duì)象的地址返回,賦給str2。因?yàn)閟tr1、str2指向同一個(gè)字符串池中的"abc"對(duì)象,所以結(jié)果為true。

String str3 = new String("abc");
String str4 = new String("abc");
// falseSystem.out.println(str3 == str4);

采用new關(guān)鍵字新建一個(gè)字符串對(duì)象時(shí),JVM首先在字符串池中查找有沒(méi)有"abc"這個(gè)字符串對(duì)象,

如果沒(méi)有,則首先在字符串池中創(chuàng)建一個(gè)"abc"字符串對(duì)象,然后再在堆中創(chuàng)建一個(gè)"abc"字符串對(duì)象,然后將堆中這個(gè)"abc"字符串對(duì)象的地址賦給str3

如果有,則不在池中再去創(chuàng)建"abc"這個(gè)對(duì)象了,直接在堆中創(chuàng)建一個(gè)"abc"字符串對(duì)象,然后將堆中的這個(gè)"abc"對(duì)象的地址賦給str4。這樣,str4就指向了堆中創(chuàng)建的這個(gè)"abc"字符串對(duì)象;

因?yàn)閟tr3和str4指向的是不同的字符串對(duì)象,結(jié)果為false。

緩存HashCode

String類(lèi)在被創(chuàng)建的時(shí)候,hashcode就被緩存到hash成員變量中,因?yàn)镾tring類(lèi)是不可變的,所以hashcode是不會(huì)改變的。這樣每次想使用hashcode的時(shí)候直接取就行了,而不用重新計(jì)算,提高了效率

public final class String
    implements java.io.Serializable, Comparable, CharSequence {

    /** Cache the hash code for the string */
    private int hash; // Default to 0
	}

可以用作HashMap的key

由于String類(lèi)不可變的特性,所以經(jīng)常被用作HashMap的key,如果String類(lèi)是可變的,內(nèi)容改變,hashCode也會(huì)改變,當(dāng)根據(jù)這個(gè)key從HashMap中取的時(shí)候有可能取不到value,或者取到錯(cuò)的value

線程安全

不可變對(duì)象天生就是線程安全的,這樣可以避免在多線程環(huán)境下對(duì)String做同步操作。

看完上述內(nèi)容,你們對(duì)Java中String類(lèi)有進(jìn)一步的了解嗎?如果還想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀。


網(wǎng)站名稱(chēng):為什么Java中String類(lèi)設(shè)置完不能改
分享URL:http://weahome.cn/article/jphgig.html

其他資訊

在線咨詢(xún)

微信咨詢(xún)

電話咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部