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

Java?String類的理解及字符串常量池介紹

 更新時間:2022年09月25日 16:12:27   作者:XIN-XIANG榮  
這篇文章主要介紹了Java?String類的理解及字符串常量池介紹,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下

一. String類簡介

1. 介紹

字符串廣泛應(yīng)用 在 Java 編程中,在 Java 中字符串屬于對象,Java 提供了 String 類來創(chuàng)建和操作字符串。

Java的String類在lang包里,java.lang.String是java字符串類,包含了字符串的值和實現(xiàn)字符串相關(guān)操作的一些方法;java.lang包里面的類都不需要手動導入,是由程序自動導入。

String表示字符串類型,屬于引用數(shù)據(jù)類型, 內(nèi)部并不存儲字符串本身 ;Java 程序中的所有字符串字面值(如 “abc” )都作為此類的實例實現(xiàn)。

在String類的實現(xiàn)源碼中,String類實例變量如下:

public static void main(String[] args) {
        // s1和s2引用的是不同對象 s1和s3引用的是同一對象
        String s1 = new String("hello");
        String s2 = new String("world");
        String s3 = s1;
        System.out.println(s1.length()); 
        // 獲取字符串長度---輸出5
        System.out.println(s1.isEmpty()); 
        // 如果字符串長度為0,返回true,否則返回false
}

字符串存儲在字符串常量池中,后文中給出具體的理解與分析。

2. 字符串構(gòu)造

String類提供的構(gòu)造方式非常多,常用的就以下三種:

public static void main(String[] args) {
        // 使用常量串構(gòu)造
        String s1 = "hello bit";
        System.out.println(s1);
    
        // 直接newString對象
        String s2 = new String("hello bit");
        System.out.println(s1);
    
        // 使用字符數(shù)組進行構(gòu)造
        char[] array = {'h','e','l','l','o','b','i','t'};
        String s3 = new String(array);
        System.out.println(s1);
    }

二. 字符串常量池(StringTable)

1. 思考?

通過下面的代碼,分析和思考字符串對象的創(chuàng)建和字符串常量池。

public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "hello";
        String s3 = new String("hello");
        String s4 = new String("hello");
        System.out.println(s1 == s2); // true
        System.out.println(s1 == s3); // false
        System.out.println(s3 == s4); // false
    }

執(zhí)行及調(diào)試結(jié)果:

思考為什么執(zhí)行結(jié)果中,創(chuàng)建的字符串的地址是一樣的,使用new String的時候比較兩個對象的地址卻不一樣,直接使用字符串常量(“ ”)進行賦值的兩個對象比較是相同的;

為什么s1和s2引用的是同一個對象,而s3和s4不是呢?

2. 介紹和分析

在Java程序中,類似于:1, 2, 3,3.14,“hello”等字面類型的常量經(jīng)常頻繁使用,為了使程序的運行速度更快、 更節(jié)省內(nèi)存,Java為8種基本數(shù)據(jù)類型和String類都提供了常量池。

為了節(jié)省存儲空間以及程序的運行效率,Java中引入了:

  • Class文件常量池:每個.Java源文件編譯后生成.Class文件中會保存當前類中的字面常量以及符號信息
  • 運行時常量池:在.Class文件被加載時,.Class文件中的常量池被加載到內(nèi)存中稱為運行時常量池,運行時常量池每個類都有一份
  • 字符串常量池(StringTable) :字符串常量池在JVM中是StringTable類,實際是一個固定大小的HashTable(一種高效用來進行查找的數(shù)據(jù)結(jié)構(gòu)),不同JDK版本下字符串常量池的位置以及默認大小是不同的:
JDK版本字符串常量池位置大小設(shè)置
Java6(方法區(qū))永久代固定大?。?009
Java7堆中可設(shè)置,沒有大小限制,默認大小:60013
Java8堆中可設(shè)置,有范圍限制,最小是1009

對1中的代碼進行分析:

直接使用字符串常量進行賦值

public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "hello";
        System.out.println(s1 == s2); // true
}

當字節(jié)碼文件加載時,字符常量串“hello”已經(jīng)創(chuàng)建好了,并保存在字符串常量池中,

當直接使用常量串賦值的時候( String s1 = “hello”;)會優(yōu)先從字符串常量池找,找到了就將該字符串引用賦值給要賦值的對象(s1和s2);

所以s1和s2內(nèi)放的都是字符串常量池中“hello”字符串所創(chuàng)建對象的引用,是相同的。

通過new創(chuàng)建String類對象

使用new來創(chuàng)建String對象,每次new都會新創(chuàng)建一個對象,每個對象的地址都是唯一的,所以s3和s4的引用是不相同的。

使用常量串創(chuàng)建String類型對象的效率更高,而且更節(jié)省空間。用戶也可以將創(chuàng)建的 字符串對象通過 intern 方式添加進字符串常量池中。

3. intern方法

intern 是一個native方法(Native方法指:底層使用C++實現(xiàn)的,看不到其實現(xiàn)的源代碼);

該方法的作用是手動將創(chuàng)建的String對象添加到常量池中。

public static void main(String[] args) {
        char[] ch = new char[]{'a', 'b', 'c'};
        String s1 = new String(ch); // s1對象并不在常量池中
        //s1.intern(); 
        //intern調(diào)用之后,會將s1對象的引用放入到常量池中
        String s2 = "abc"; // "abc" 在常量池中存在了,s2創(chuàng)建時直接用常量池中"abc"的引用
        System.out.println(s1 == s2);

}

// 輸出false
// 將上述方法打開之后,就會輸出true

三. 面試題:String類中兩種對象實例化的區(qū)別

JDK1.8中

  • String str = “hello”;只會開辟一塊堆內(nèi)存空間,保存在字符串常量池中,然后str共享常量池中的
  • String對象String str = new String(“hello”);會開辟兩塊堆內(nèi)存空間,字符串"hello"保存在字符串常量池中,然后用常量池中的String對象給新開辟的String對象賦值。
  • String str = new String(new char[]{‘h’, ‘e’, ‘l’, ‘l’, ‘o’})先在堆上創(chuàng)建一個String對象,然后利用copyof將重新開辟數(shù)組空間,將參數(shù)字符串數(shù)組中內(nèi)容拷貝到String對象中

四. 字符串的不可變性

String是一種不可變對象. 字符串中的內(nèi)容是不可改變。字符串不可被修改,是因為:

String類在設(shè)計時就是不可改變的,String類實現(xiàn)描述中已經(jīng)說明了

String類中的字符實際保存在內(nèi)部維護的value字符數(shù)組中,該圖還可以看出:

  • String類被final修飾,表明該類不能被繼承
  • value被修飾被final修飾,表明value自身的值不能改變,即不能引用其它字符數(shù)組,但是其引用空間中的內(nèi)容可以修改。
  • 字符串真正不能被修改的原因是,存儲字符串的value是被private修飾的,只能在String類中使用,但String中并沒有提供訪問value的公開方法

網(wǎng)上有些人說:字符串不可變是因為其內(nèi)部保存字符的數(shù)組被final修飾了,因此不能改變;這種說法是錯誤的,不是因為String類自身,或者其內(nèi)部value被final修飾而不能被修改; final修飾類表明該類不想被繼承,final修飾引用類型表明該引用變量不能引用其他對象,但是其引用對象中的內(nèi) 容是可以修改的。

所有涉及到可能修改字符串內(nèi)容的操作都是創(chuàng)建一個新對象,改變的是新對象

比如 replace 方法:

注意:

盡量避免直接對String類型對象進行修改,因為String類是不能修改的,所有的修改都會創(chuàng)建新對象,效率非常低下。

public static void main(String[] args) {
        String str = "";
        for (int i = 0; i < 100; i++) {
            str += i;
        }
        System.out.println(str);
}

執(zhí)行結(jié)果:

這種方式不推薦使用,因為其效率非常低,中間創(chuàng)建了好多臨時對象。

下圖是上面代碼的匯編,可以看到每一次循環(huán)都需要重新創(chuàng)建一個StringBuuilder對象,效率非常低。

  • 創(chuàng)建一個StringBuild的對象,假設(shè)為temp
  • 將str對象append(追加)temp之后
  • 將"world"字符串a(chǎn)ppend(追加)在temp之后
  • .temp調(diào)用其toString方法構(gòu)造一個新的String對象

將新String對象的引用賦直給str

將上述匯編過程轉(zhuǎn)化為類似代碼如下:

public static void main(String[] args) {
        String str = "";
        for (int i = 0; i < 100; i++) {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(str);
            stringBuilder.append(i);
            str = stringBuilder.toString();
        }
        System.out.println(str);
}

這里可以將上述代碼優(yōu)化一下進行對比,只創(chuàng)建一次StringBuilder即可:

public static void main8(String[] args) {
        String str = "";
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(str);
        for (int i = 0; i < 100; i++) {
            stringBuilder.append(i);
        }
        System.out.println(stringBuilder);
}

通過下面的代碼對比String和StringBuildder、StringBuffer效率上的差異:

ublic static void main(String[] args) {
        long start = System.currentTimeMillis();
        String s = "";
        for(int i = 0; i < 10000; ++i){
            s += i;
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    
        start = System.currentTimeMillis();
        StringBuffer sbf = new StringBuffer("");
        for(int i = 0; i < 10000; ++i){
            sbf.append(i);
        }
        end = System.currentTimeMillis();
        System.out.println(end - start);
    
        start = System.currentTimeMillis();
        StringBuilder sbd = new StringBuilder();
        for(int i = 0; i < 10000; ++i){
            sbd.append(i);
        }
        end = System.currentTimeMillis();
        System.out.println(end - start);
}

執(zhí)行結(jié)果:

可以看出在對String類進行修改時,效率是非常慢的,因此:盡量避免對String的直接需要,如果要修改建議盡量 使用StringBuffer或者StringBuilder。

到此這篇關(guān)于Java String類的理解及字符串常量池介紹的文章就介紹到這了,更多相關(guān)Java String類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深度解析Spring?Filter方法示例

    深度解析Spring?Filter方法示例

    這篇文章主要為大家介紹了深度解析Spring?Filter用法示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • Java數(shù)組索引異常產(chǎn)生及解決方案

    Java數(shù)組索引異常產(chǎn)生及解決方案

    這篇文章主要介紹了Java數(shù)組索引異常產(chǎn)生及解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • Mybatis千萬級數(shù)據(jù)查詢的解決方式,避免OOM問題

    Mybatis千萬級數(shù)據(jù)查詢的解決方式,避免OOM問題

    這篇文章主要介紹了Mybatis千萬級數(shù)據(jù)查詢的解決方式,避免OOM問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Java中double保留兩位小數(shù)的多種方法

    Java中double保留兩位小數(shù)的多種方法

    這篇文章主要給大家介紹了關(guān)于Java中double保留兩位小數(shù)的多種方法,對于double數(shù)據(jù)類型進行計算發(fā)生的精度丟失的情況,可以按照自己的需求選擇任意方式,需要的朋友可以參考下
    2023-07-07
  • 快速了解Java中NIO核心組件

    快速了解Java中NIO核心組件

    這篇文章主要介紹了快速了解Java中NIO核心組件,涉及相關(guān)介紹及完整實例,具有一定借鑒價值,需要的朋友可以參考下。
    2017-12-12
  • JavaWeb實現(xiàn)文件的上傳與下載

    JavaWeb實現(xiàn)文件的上傳與下載

    這篇文章主要為大家詳細介紹了JavaWeb實現(xiàn)文件的上傳與下載,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • SpringBoot多環(huán)境日志配置方式

    SpringBoot多環(huán)境日志配置方式

    SpringBoot?默認使用LogBack日志系統(tǒng),默認情況下,SpringBoot項目的日志只會在控制臺輸入,本文給大家介紹SpringBoot多環(huán)境日志配置方式,需要的朋友可以參考下
    2024-08-08
  • Springboot整合Shiro的代碼實例

    Springboot整合Shiro的代碼實例

    這篇文章主要介紹了Springboot整合Shiro的代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • Java利用釘釘機器人實現(xiàn)發(fā)送群消息

    Java利用釘釘機器人實現(xiàn)發(fā)送群消息

    這篇文章主要為大家詳細介紹了Java語言如何通過釘釘機器人發(fā)送群消息通知,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下
    2022-09-09
  • Java Spring Boot實現(xiàn)簡易掃碼登錄詳解

    Java Spring Boot實現(xiàn)簡易掃碼登錄詳解

    這篇文章主要為大家詳細介紹了java Spring Boot實現(xiàn)app掃碼登錄功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-09-09

最新評論

澎湖县| 博野县| 格尔木市| 宣化县| 永安市| 台山市| 饶阳县| 庄河市| 晋中市| 扎兰屯市| 集贤县| 白山市| 桦南县| 平遥县| 扎赉特旗| 巨野县| 济源市| 天长市| 石楼县| 阳高县| 西乡县| 本溪| 九龙坡区| 海南省| 舒城县| 静海县| 东兴市| 沅陵县| 休宁县| 弥渡县| 九江市| 陇南市| 若尔盖县| 仙游县| 蒲城县| 福清市| 德江县| 大同市| 肇东市| 方城县| 日土县|