Java String類相關知識梳理(含字元串常量池(String Pool)知識)

来源:https://www.cnblogs.com/laipimei/archive/2020/01/10/12177607.html
-Advertisement-
Play Games

目錄 1. String類是什麼 1.1 定義 1.2 類結構 1.3 所在的包 2. String類的底層數據結構 3. 關於 intern() 方法(重點) 3.1 作用 3.2 字元串常量池(String Pool) 4. String類所用的連接符 5. String類的主要作用(簡) 正文 ...


目錄

1. String類是什麼

  1.1 定義

  1.2 類結構

  1.3 所在的包

2. String類的底層數據結構

3. 關於 intern() 方法(重點)

  3.1 作用

  3.2 字元串常量池(String Pool)

4. String類所用的連接符

5. String類的主要作用(簡)

 

正文

1. String類是什麼

  1.1 定義

  String類表示字元串。Java程式中的所有字元串都是這個String的實例,比如"abc"。字元串為常數,它們的值在創建之後不能更改。因為字元串對象是不可變的,避免了現線程安全問題的出現,所以可以共用它們。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

  問:“字元串為常數,它們的值在創建之後不能更改”——①這句話的具體表現(從String的使用角度出發)?②為什麼要一經創建就不可更改?③怎麼做到一經創建就不可更改的?

    答:

    ①通過調用String的方法我們可以發現,String並未真正提供“字元串的修改”方法,諸如replace這類的字元串替換方法,也只是創建一個新的字元串來替換,而非在原字元串上進行替換;

    ②這個問題從字元串的使用場景來解釋比較好理解:從用戶使用時的安全性考慮(線程安全),八種基本數據類型的“複製”是再新創建一份相同的數據,而String其實也相當於是一種基本的數據類型,只是它有引用,比較複雜一些,所以字元串要一經創建就不能更改。

    ③封裝:雖然String的底層數據結構是char數組(數組的內容是可以更改的),但是,String將該欄位聲明為private,且並不對外暴露修改數組內容的方法。

  1.2 類結構

public final class String implements java.io.Serializable, Comparable<String>, CharSequence{……}

  ① final:String類不能被繼承;

  ② Serializable:可序列化;

  ③ Comparable<String>:用於字元串之間的比較;

  1.3 所在的包:java.lang

  java.lang包是java語言的核心,它提供了java中的基礎類。包括基本Object類、Class類、String類、基本類型的包裝類、基本的數學類等等最基本的類。

 

2. String類的底層數據結構

private final char value[];//不可變的字元數組

  問1. 如果說String的底層數據結構是“不可變的char數組”,那不應該是聲明為“ private final char[] value;”嗎?

    答:這也是數組的一種聲明方式,只是比較少見、少用,或許因為歷史原因所以String保留使用著這種不常用的數組聲明方式。

  問2. 不可變的字元數組的聲明只能保證String對象的引用不可變,而用了char數組來作為存儲結構,只能保證字元串一經聲明其長度不可變,但是數組中存儲的內容時可以改變的,從何保證字元串一經聲明就不能再變呢?

    答:見 1.1的第③點;

  

3. 關於 intern() 方法(重點)

  3.1 作用:該方法用於返回字元串對象的規範表示形式。

public native String intern();// native方法,看不到具體實現。

  當調用intern方法時:

    ①如果字元串常量池中已經包含了一個由equals(object)方法確定的String對象的字元串,則返回池中的字元串。

    ②否則,將這個 String對象添加到池中(這是JDK1.8中intern()方法的註釋給出的說明,但通過下麵的測試,我認為是“將這個String對象的字元串添加到池中”會更好理解),並返回對這個String對象的引用。

    @Test
    public void test() {

        // 池中沒有相應的字元串內容:
        String s1 = new String("hello");// 在堆中生成"hello"字元串對象
        String s2 = s1.intern();// 執行“s1.intern()”時,String Pool中沒有"hello",會直接先將s1對象複製到池中
        System.out.println(s1 == s2); // false
        System.out.println(s1.intern()); // hello

        // 池中有:
        String s3 = "world"; // 直接在String Pool中生成"world"字元串
        String s4 = s3.intern(); // 從池中拿"world"字元串返回給s4
        System.out.println(s3 == s4); // true
    }

  3.2 字元串常量池(String Pool)

  字元串常量池最初是空的,由類 String私下維護。

  (1)在哪兒

    在JDK6及之前版本:字元串常量池是放在永久代中;

    在JDK7版本中:字元串常量池被移到了堆中。

  (2)數據結構

    在HotSpot VM中字元串常量池是通過一個StringTable類(一個Hash表,並非java實現類,所以知道即可)實現的;這個StringTable在每個HotSpot VM的實例中只有一份,被所有的類共用;

  (3)存放的內容

    在JDK6及之前版本:String Pool里放的都是字元串常量;

    在JDK7.0中:由於String.intern()發生了改變,因此String Pool中也可以存放放於堆內的字元串對象的引用。

  (4)特性:常量池中不存在兩個相同的對象

  (5)字元串常量池存在的意義(為什麼要有它?):避免字元串常量的重覆創建,節省記憶體空間。

  (6)什麼情況下生成的字元串才會被放到String Pool中?

    ① 字面量:代碼中直接使用雙引號引著的字元串都會被存儲到字元串常量池中,如:String abc = "abc";;

    ② 調用String的 intern()方法,如果字元串內容是字元串常量池中沒有的,那麼會先複製一份內容到字元串常量池中;

 

4. String類所用的連接符

  Java語言為“+”連接符以及將對象轉換為字元串提供了特殊的支持:

  字元串對象可以使用“+”連接其他對象。其實字元串連接是通過StringBuilder(或 StringBuffer)及其 append()方法 實現的。

  字元串轉換是通過 toString()方法實現的,該方法由Object定義,並由Java中的所有類繼承。

 

5. String類的主要作用(簡) 

  ①檢查序列的單個字元、
  ②比較字元串、
  ③搜索字元串、
  ④提取子字元串
  ⑤創建一個字元串的副本的方法,
  ⑥大小寫轉換;
  ⑦更多;


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、什麼是OAuth? OAuth是一個授權規範,可以使A應用在受限的情況下訪問B應用中用戶的資源(前提是經過了該用戶的授權,而A應用並不需要也無法知道用戶在B應用中的賬號和密碼),資源通常以REST API的方式暴露。 二、什麼是OAuth2.0? 有2.0自然有1.0,相比1.0,2.0有如下不 ...
  • 1. 前言 在使用 OAuth2.0 中 Authorization Server (授權伺服器)是一個迴避不了的設施,在大多數情況下我們調用的是一些知名的、可靠的、可信任的第三方平臺,比如 QQ、微信、微博、github 等。我們的應用只作為 Client 進行註冊接入即可。也就是說我們只需要實現 ...
  • C語言中,a=b=c,a=b==c,a==(b=c),a==(b==c)有什麼區別 main(){inta=1,b=2,c=3;printf("%d,%d,%d,%d\n",a=b=c,a=b==c,a==(b=c),a==(b==c));}... 百度知道: 首先謝謝樓主,這個問題真好!我剛纔的回 ...
  • 天氣降溫,感情卻升溫了? 上午剛到公司,就收到小Q發來的靈魂拷問: “Q仔!要不然下午請個假!我帶你去精神科看看!?”我實在忍不了,脫口而出。 話音未落,前排的運營小花回頭看向小Q,莞爾一笑,百媚橫生。 這個悶騷小伙子什麼時候勾搭上運營一枝花了?我正要追問,小Q看穿了我的意圖,故作正經:“咳咳!工作 ...
  • [TOC] AJAX簡介 AJAX(Asynchronous Javascript And XML)翻譯成中文就是“非同步的Javascript和XML”。即使用Javascript語言與伺服器進行非同步交互,傳輸的數據為XML(當然,傳輸的數據不只是XML)。 AJAX 不是新的編程語言,而是一種使用 ...
  • 區別 1.#將傳入的數據都當成一個字元串,會對自動傳入的數據加一個雙引號。如:order by #user_id#,如果傳入的值是111,那麼解析成sql時的值為order by "111", 如果傳入的值是id,則解析成的sql為order by "id". 2.將傳入的數據直接顯示生成在sql中 ...
  • public void method1() { Integer i = new Integer(1); Integer j = new Integer(1); System.out.println(i == j); Integer m = 1; Integer n = 1; System.out.p ...
  • 開發環境: Windows操作系統開發工具:MyEclipse/Eclipse + JDK+ Tomcat + MySQL 資料庫項目簡介:網路考試系統主要用於實現高校線上考試,基本功能包括:自動組捲、試卷發佈、試卷批閱、試卷成績統計等。本系統結構如下:(1)學生端: 登錄模塊:登錄功能; 網路考試 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...