日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

Java String类源码解析

發(fā)布時(shí)間:2025/7/25 java 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java String类源码解析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

String直接繼承Object

含有一個(gè)char[] value,還有一個(gè)int hash默認(rèn)值為0

new String()的構(gòu)造產(chǎn)生的是一個(gè)值為””的字符數(shù)組

String(char value[], int offset, int count)當(dāng)count=0且offset<=value.length時(shí)構(gòu)造一個(gè)值為””的字符串。offset>0且offset+count<=value.length時(shí)復(fù)制該部分子串。其余情況都會(huì)拋錯(cuò)。

字符數(shù)據(jù)類型是一個(gè)采用UTF-16編碼表示Unicode代碼點(diǎn)的代碼單元。大多數(shù)的常用Unicode字符使用一個(gè)代碼單元就可以表示,而輔助字符需要一對(duì)代碼單元表示。而length返回的是UTF-16下的代碼單元的數(shù)量,而codePointCount返回的是代碼點(diǎn)的數(shù)量。對(duì)于大部分人工輸入的字符,這兩者是相等的,會(huì)出現(xiàn)length比codePointCount長(zhǎng)的通常是某些數(shù)學(xué)或者機(jī)器符號(hào),需要兩個(gè)代碼單元來表示一個(gè)代碼點(diǎn)。

對(duì)于返回char[]的方法,底層調(diào)用的是System.arraycopy方法,這也是高效的數(shù)組拷貝函數(shù)。

getBytes方法會(huì)調(diào)用StringCoding.encode返回序列化后的byte[]

關(guān)于String a == String b的判斷,是指a和b指向內(nèi)存中的同一個(gè)對(duì)象,凡是new String初始化的對(duì)象,都不會(huì)產(chǎn)生a==b的情況,因?yàn)樗麜?huì)新開辟一個(gè)對(duì)象空間,然后復(fù)制value的值,僅當(dāng)b=a初始化時(shí)a==b成立。

public static void main(String args[]) {String a, b;a = "123";b = "123";System.out.println(a==b);//truea = "123";b = new String("123");System.out.println(a==b);//falsea = new String("123");b = new String("123");System.out.println(a==b);//falsea = "123";b = new String(a);System.out.println(a==b);//falsea = new String("123");b = a;System.out.println(a==b);//true}

而a.equals(b)先判斷a == b是否成立,再判斷b是否是String類,然后逐個(gè)比較value數(shù)組的值是否相等。equalsIgnoreCase在此基礎(chǔ)上忽略大小寫的區(qū)別

a.compareTo(b)比較a和b第一個(gè)不相等字符的差值,若都相等則比較長(zhǎng)度差值。compareToIgnoreCase多一個(gè)忽略大小寫的區(qū)別。regionMatches(int toffset, String other, int ooffset, int len)則是比較a從toffset開始和other從ooffset開始長(zhǎng)度為len的部分是否相等。

startsWith(String prefix, int toffset)字符串從tooffset位置開始和prefix是否相等。endsWith(String suffix)字符串結(jié)尾和suffix等長(zhǎng)部分是否相等。

hashCode()調(diào)用時(shí),若hash值為0且字符串長(zhǎng)度不為0,則要計(jì)算hash值,方法是value數(shù)組化為31進(jìn)制

indexOf是返回第一個(gè)出現(xiàn)的指定值的位置,可以通過fromIndex來指定開始查找的位置,而indexOfSupplementary是忽略大小寫的該方法。lastIndexOf則是從尾部開始查找最后一個(gè)。

substring根據(jù)指定的位置返回一個(gè)新的子字符串,若指定位置不符合原字符串的長(zhǎng)度,則拋錯(cuò)。

a.concat(String str)新建一個(gè)字符串內(nèi)容是a+str并返回,不會(huì)修改a原本的值

public static void main(String args[]) {String a, b;a = "123";b = "123";a.concat(b);System.out.println(a);//123System.out.println(a.concat(b));//123123a = a.concat(b);System.out.println(a);//123123}

replace(char oldChar, char newChar)生成一個(gè)新的字符串,將原字符串中的oldChar字符全部替換為newChar,不會(huì)改變?cè)址闹怠eplaceAll(String regex, String replacement)和前一個(gè)方法相比,參數(shù)regex是正則表達(dá)式,其余相同。

public static void main(String args[]) {String a;a = "12131";a.replace("1", "a");System.out.println(a);//12131a = a.replace("1", "a");System.out.println(a);//a2a3a}

split(String regex, int limit)將字符串按照給定的正則表達(dá)式分割為字符串組,limit是分割產(chǎn)生的數(shù)組最大數(shù)量,對(duì)于多余部分不做分割全部保留在最后一個(gè)字符串中。

public static void main(String args[]) {String a;a = "1,2,3,4";String[] b = a.split(",");for(String t : b){System.out.print(t + " ");//1 2 3 4 }System.out.println("");String[] c = a.split(",", 3);for(String t : c){System.out.print(t + " ");//1 2 3,4 }}

toCharArray()復(fù)制出一個(gè)新的char[]而不是直接返回value

trim()生成一個(gè)新的字符串,去掉頭部的所有空格

public native String intern()這個(gè)方法的作用是在常量池當(dāng)中尋找是否已經(jīng)存在該字符串,若已存在則返回該引用,若不存在則在常量池新建。從上面的源碼分析中,我們可以看出String的所有操作都是返回一個(gè)新的字符串,對(duì)自身是沒有修改的,String被設(shè)計(jì)為一個(gè)不可變的final對(duì)象,理由有以下幾點(diǎn):

1. 字符串常量池的需要。字符串常量池的誕生是為了提升效率和減少內(nèi)存分配。、因?yàn)镾tring的不可變性,常量池很容易被管理和優(yōu)化。

2. 安全性考慮。正因?yàn)槭褂米址膱?chǎng)景如此之多,所以設(shè)計(jì)成不可變可以有效的防止字符串被有意或者無意的篡改。(通過反射或者Unsafe直接操作內(nèi)存的手段也可以實(shí)現(xiàn)對(duì)所謂不可變String的修改)。

3. 作為HashMap、HashTable等hash型數(shù)據(jù)key的必要。因?yàn)椴豢勺兊脑O(shè)計(jì),jvm底層很容易在緩存String對(duì)象的時(shí)候緩存其hashcode,這樣在執(zhí)行效率上會(huì)大大提升。

public static void main(String args[]) {String a, b;a = "123";b = new String(a).intern();System.out.println(a == b);//truea = "12" + "3";b = "123";System.out.println(a == b);//truea = "12" + "3";b = new String("123");System.out.println(a == b);//falsea = "12" + "3";b = new String("123").intern();System.out.println(a == b);//truea = new String("123");b = a.intern();System.out.println(a == b);//false}

從上面一段代碼的運(yùn)行結(jié)果我們可以看到,intern()會(huì)從常量池尋找指定的字符串,指向同一個(gè)常量池對(duì)象的時(shí)候,a==b就是成立的。這里說明一下最后一個(gè)case,首先常量池存在了”123”,然后a獲得的引用是另一個(gè)”123”(因?yàn)槭莕ew String得到的對(duì)象),而b得到的是常量池中第一個(gè)”123”的引用,所以a!=b。對(duì)于字符串相加的操作"12" + "3",操作過后常量池內(nèi)會(huì)有3個(gè)字符串,"12" ?"3" “123”

?

轉(zhuǎn)載于:https://www.cnblogs.com/graywind/p/9400616.html

總結(jié)

以上是生活随笔為你收集整理的Java String类源码解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。