最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java基礎(chǔ)類學(xué)習(xí)之String詳解

 更新時(shí)間:2022年12月27日 08:19:01   作者:拿了桔子跑-范德依彪  
這篇文章主要為大家詳細(xì)介紹了Java基礎(chǔ)類中String的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定的幫助,需要的可以參考一下

1 String不可變性

  • String類被聲明為 final,因此它不可被繼承。
  • 內(nèi)部使用char數(shù)組存儲(chǔ)數(shù)據(jù),該數(shù)組被聲明為final,這意味著value數(shù)組初始化之后就不能再指向其它數(shù)組。
  • String內(nèi)部沒有改變value數(shù)組的方法
  • String類中所有修改String值的方法,如果內(nèi)容沒有改變,則返回原來的String對(duì)象引用,如果改變了,創(chuàng)建了一個(gè)全新的String對(duì)象,包含修改后的字符串內(nèi)容,最初的String對(duì)象沒有任何改變。(目的:節(jié)約存儲(chǔ)空間、避免額外的開銷)
//String的類聲明以及value字段代碼:
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    private final char value[]; //字符數(shù)組存儲(chǔ)String的內(nèi)容
    /** Cache the hash code for the string */
    private int hash; // Default to 0
}

不可變的驗(yàn)證分析:

public class Immutable {
    public static String upcase(String s) {
        return s.toUpperCase();
    }
    public static void main(String[] args) {
        String q = "howdy";
        System.out.println(q); // howdy
        String qq = upcase(q);
        System.out.println(qq); // HOWDY
        System.out.println(q); // howdy
    }
} /* 輸出:
    howdy
    HOWDY
    howdy
    *///:~
  • 當(dāng)把q傳給upcase0方法時(shí),實(shí)際傳遞的是引用的一個(gè)拷貝。
  • upcase0方法中,傳入引用s,只有upcase0運(yùn)行的時(shí)候,局部引用s才存在。一旦upcase0運(yùn)行結(jié)束,s就消失。upcaseO的返回值是最終結(jié)果的引用。
  • 綜上,upcase()返回的引用已經(jīng)指向了一個(gè)新的對(duì)象,而原本的q則還在原地。

延伸結(jié)論:

String對(duì)象作為方法的參數(shù)時(shí),都會(huì)復(fù)制一份引用,參數(shù)傳遞是引用的拷貝

2 不可變的好處

1. 可以緩存 hash 值

String的hash值經(jīng)常被使用,例如String用做HashMap的key。不可變的特性可以使得hash值也不可變,因此只需要進(jìn)行一次計(jì)算。

2. String Pool 的需要

如果一個(gè)String對(duì)象已經(jīng)被創(chuàng)建過了,那么就會(huì)從 String Pool 中取得引用。只有String是不可變的,才可能使用 String Pool。

3. 線程安全

String不可變性天生具備線程安全,可以在多個(gè)線程中安全地使用。

3 String+和StringBuilder效率差異

String使用“+”表示字符串拼接

先說結(jié)論:

  • “+”操作,javac編譯器會(huì)自動(dòng)優(yōu)化為StringBuilder.append() 調(diào)用。
  • StringBuilder要比“+”操作高效
  • 涉及循環(huán)追加的,手動(dòng)創(chuàng)建StringBuilder對(duì)象操作比“+”操作編譯器優(yōu)化,更高效

驗(yàn)證:

public class StringBuilderTest {
    public static void main(String[] args) {
        String s1 = "ABC";
        String s2 = "123";
        String result = s1+s2;
        System.out.println(result);
    }
}

編譯并查看字節(jié)碼:javap -verbose StringBuilderTest.class

執(zhí)行過程:

調(diào)用了2次append()方法,最后調(diào)用StringBuilder.toString()返回最終結(jié)果

為什么StringBuilder要比+高效?

  • +操作,按照:每次追加都創(chuàng)建新的String對(duì)象,把字符加入value數(shù)組中。這里產(chǎn)生一次對(duì)象創(chuàng)建操作,以及對(duì)應(yīng)的垃圾回收
  • StringBuilder的底層數(shù)組value也是用到了char[],但它沒有聲明為final,故它可變,所以追加內(nèi)容時(shí)不用創(chuàng)建新的數(shù)組,而是直接修改value
  • StringBuilder比+省去String對(duì)象創(chuàng)建以及垃圾回收的開銷,因此效率更高。

源碼追溯:

 //StringBuilder.append()
 @Override
    public StringBuilder append(char c) {
        super.append(c);
        return this;
    }
   // 父類 AbstractStringBuilder.append()
     @Override
    public AbstractStringBuilder append(char c) {
        ensureCapacityInternal(count + 1);
        value[count++] = c;
        return this;
    }
    //AbstractStringBuilder value 字段
    abstract class AbstractStringBuilder implements Appendable, CharSequence {
    //The value is used for character storage.
    char[] value; // 沒有聲明為final,因此value可變
    }

手動(dòng)實(shí)現(xiàn)StringBuilder對(duì)象操作比編譯器自行優(yōu)化,更高效

  • 通過字節(jié)碼分析可知(我這里省去了,可以自己實(shí)現(xiàn)驗(yàn)證):循環(huán)部分的代碼更簡(jiǎn)短、更簡(jiǎn)單,而且它只生成了一個(gè)StringBuilder對(duì)象
  • 顯式地創(chuàng)建StringBuilder還允許你預(yù)先為其指定大小。如果你已經(jīng)知道最終的字符串大概有多長(zhǎng),那預(yù)先指定StringBuilder的大小可以避免多次重新分配緩沖

當(dāng)你為一個(gè)類編寫toString方法時(shí),如果字符串操作比較簡(jiǎn)單,那就可以信賴編譯器,它會(huì)為你合理地構(gòu)造最終的字符串結(jié)果。但是,如果你要在toString0方法中使用循環(huán),那么最好自己創(chuàng)建一個(gè)StringBuilder對(duì)象來實(shí)現(xiàn)。

4 String, StringBuffer and StringBuilder

可變性

  • String 不可變
  • StringBuffer和StringBuilder可變

線程安全

  • String不可變,因此是線程安全的
  • StringBuilder 不是線程安全的
  • StringBuffer 是線程安全的,內(nèi)部使用synchronized進(jìn)行同步

效率

  • 如果要操作少量的數(shù)據(jù)用String
  • 單線程環(huán)境且字符串緩沖區(qū)涉及大量數(shù)據(jù) StringBuilder
  • 多線程環(huán)境且字符串緩沖區(qū)涉及大量數(shù)據(jù) StringBuffer

5 String與JVM內(nèi)存管理

一、引入字符串常量池

  • Javac編譯后,字節(jié)碼文件中有一塊區(qū)域:常量池,存儲(chǔ)了包括類中聲明的字符串常量值等字面量
  • 運(yùn)行時(shí),JVM開辟實(shí)際內(nèi)存空間:字符串常量值寫入了字符串常量池,屬于方法區(qū)的一部分。

案例1

String s1 = "win";
String s2 = "win";
System.out.println(s1==s2);
//輸出結(jié)果:true
//引用 s1  s2 的值等于win在字符串常量池的地址值

結(jié)論:

引用 s1 s2 的值等于win在字符串常量池的地址值

分析字節(jié)碼的執(zhí)行過程:

案例2

public class StringPool {
    public static void main(String[] args) {
        String s3 = new String("win");
        String s4 = new String("win");
        System.out.println(s3==s4);//false
    }
}

結(jié)論:

通過new操作符創(chuàng)建的字符串對(duì)象不指向字符串池中的任何對(duì)象。

字節(jié)碼分析:

綜上:

public class StringPool {
    public static void main(String[] args) {
        String s1 = "win";
        String s2 = "win";
        String s3 = new String("win");
        String s4 = new String("win");

        System.out.println(s1==s2);//true
        System.out.println(s1==s3);//false
        System.out.println(s3==s4);//false
    }
}

6 String api方法

從這個(gè)表中可以看出,當(dāng)需要改變字符串的內(nèi)容時(shí),String類的方法都會(huì)返回一個(gè)新的String對(duì)象。同時(shí),如果內(nèi)容沒有發(fā)生改變,String的方法只是返回指向原對(duì)象的引用而已。這可以節(jié)約存儲(chǔ)空間以及避免額外的開銷。

以上就是Java基礎(chǔ)類學(xué)習(xí)之String詳解的詳細(xì)內(nèi)容,更多關(guān)于Java String類的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章

相關(guān)文章

  • Spring?Boot使用MyBatis進(jìn)行兩個(gè)表的關(guān)聯(lián)

    Spring?Boot使用MyBatis進(jìn)行兩個(gè)表的關(guān)聯(lián)

    本文主要介紹了Spring?Boot使用MyBatis進(jìn)行兩個(gè)表的關(guān)聯(lián),通過實(shí)例演示了如何使用MyBatis的XML映射文件和注解實(shí)現(xiàn)關(guān)聯(lián)操作,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • Spring Boot RestTemplate提交表單數(shù)據(jù)的三種方法

    Spring Boot RestTemplate提交表單數(shù)據(jù)的三種方法

    本篇文章主要介紹了Spring Boot RestTemplate提交表單數(shù)據(jù)的三種方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-03-03
  • JAVA系統(tǒng)中Spring?Boot應(yīng)用程序的配置文件application.yml使用詳解

    JAVA系統(tǒng)中Spring?Boot應(yīng)用程序的配置文件application.yml使用詳解

    這篇文章主要介紹了JAVA系統(tǒng)中Spring?Boot應(yīng)用程序的配置文件application.yml的相關(guān)資料,application.yml是Spring?Boot應(yīng)用程序的配置文件,定義了服務(wù)器、Spring、日志、安全及其他配置屬性,確保應(yīng)用程序正確啟動(dòng)和運(yùn)行,需要的朋友可以參考下
    2025-01-01
  • Java中的HashMap內(nèi)存泄漏問題詳解

    Java中的HashMap內(nèi)存泄漏問題詳解

    這篇文章主要介紹了Java中的HashMap內(nèi)存泄漏問題詳解,WeakHashMap中的key是弱引用,如果再使用之后沒有及時(shí)remove掉這個(gè)key,那么當(dāng)GC時(shí)key就可能會(huì)被回收,導(dǎo)致key對(duì)應(yīng)的value對(duì)象占用的內(nèi)存無法回收進(jìn)而導(dǎo)致內(nèi)存泄漏,需要的朋友可以參考下
    2023-09-09
  • Java泛型中<?>和<T>的區(qū)別淺析

    Java泛型中<?>和<T>的區(qū)別淺析

    <T>和<?>的區(qū)別 <T>是參數(shù)類型,常常用于泛型類或泛型方法的定義,下面這篇文章主要給大家介紹了關(guān)于Java泛型中<?>和<T>區(qū)別的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • Intellij Idea插件開發(fā)之創(chuàng)建項(xiàng)目層級(jí)的右鍵菜單

    Intellij Idea插件開發(fā)之創(chuàng)建項(xiàng)目層級(jí)的右鍵菜單

    這篇文章主要介紹了Intellij Idea插件開發(fā)之創(chuàng)建項(xiàng)目層級(jí)的右鍵菜單,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-02-02
  • Java線程優(yōu)先級(jí)示例代碼

    Java線程優(yōu)先級(jí)示例代碼

    使用過Bit下載軟件的同學(xué)應(yīng)該很清楚,我們有多個(gè)下載任務(wù)同時(shí)執(zhí)行,而其中的某一個(gè)或多個(gè)是非常重要的,于是給這些任務(wù)設(shè)定一個(gè)高度優(yōu)先,以便任務(wù)可以獲取更多的帶寬盡早完成下載
    2013-09-09
  • java中hashCode方法與equals方法的用法總結(jié)

    java中hashCode方法與equals方法的用法總結(jié)

    總的來說,Java中的集合(Collection)有兩類,一類是List,再有一類是Set。前者集合內(nèi)的元素是有序的,元素可以重復(fù);后者元素?zé)o序,但元素不可重復(fù)
    2013-10-10
  • Java 實(shí)現(xiàn)簡(jiǎn)易教務(wù)管理系統(tǒng)的代碼

    Java 實(shí)現(xiàn)簡(jiǎn)易教務(wù)管理系統(tǒng)的代碼

    這篇文章主要介紹了Java 實(shí)現(xiàn)簡(jiǎn)易教務(wù)管理系統(tǒng)的代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • jQuery 動(dòng)畫效果代碼分享

    jQuery 動(dòng)畫效果代碼分享

    本文給大家分享一段關(guān)于jquery實(shí)現(xiàn)的動(dòng)畫效果,代碼簡(jiǎn)單易懂,非常不錯(cuò),感興趣的朋友參考下
    2016-11-11

最新評(píng)論

岳阳市| 崇州市| 迭部县| 扎鲁特旗| 朔州市| 镇巴县| 株洲市| 芷江| 惠东县| 台山市| 四川省| 田林县| 福建省| 庆城县| 海林市| 杭锦后旗| 库伦旗| 疏勒县| 从江县| 公安县| 临沂市| 永和县| 冕宁县| 靖宇县| 遂溪县| 淮安市| 且末县| 高邮市| 玛曲县| 观塘区| 长武县| 广水市| 竹北市| 大洼县| 清丰县| 雅江县| 保定市| 谢通门县| 丽江市| 昌宁县| 吉木萨尔县|