一、String類的特性
- 不可變性
String對象一旦創建,內容不可更改,任何修改操作都會生成新對象。 - 字符串常量池
字符串字面量(如"abc"
)直接存儲在常量池中,重復字面量共享同一內存地址。 - 創建方式
雖然都是字符串但在Java中,字符串的存儲位置取決于其創建方式:通過字面量(如"abc"
)創建的字符串存儲在字符串常量池中,而通過new String()
創建的字符串對象則存儲在堆內存中。此外,字符串常量池的具體位置隨JDK版本不同而變化(如JDK1.7后移至堆內存)
String s1 = "直接賦值"; // 常量池中創建
String s2 = new String("new對象"); // 存儲在堆中,創建新對象
二、字符串創建與初始化
1. 構造方法
//最直接最常用的方法
String s1 = "abc";
System.out.println(s1);//abc//使用new的方式來獲取一個字符串對象
String s2 = new String();//傳遞一個字符串,根據傳遞的字符串內容再創建一個新的字符串對象
String s3 = new String("abc");//將一個字符數組變成字符串,根據字符數組的內容再創建一個新的字符串對象
char[] chs = {'a', 'b', 'c', 'd'};
String s4 = new String(chs);//傳遞一個字節數組,根據字節數組的內容再創建一個新的字符串對象
byte[] bytes = {97, 98, 99, 100};
String s5 = new String(bytes);//abcd
2. 內存存儲方式
棧內存中存放的是方法,方法運行時會壓棧;
堆內存中存放的是對象,new出來的實例對象都會跑到這里來;
方法區存放的是字節碼文件,用到什么類就把他的字節碼文件臨時加載到方法區中;
但是,在有一塊特殊的代碼區就是“串池”,采用直接賦值的方式創造出來的字符串都在串池里面,而串池就在堆內存中放著;
當使用雙引號直接賦值時,系統會檢查該字符串在串池中是否存在;如果不存在則創建新的;如果存在則復用;
3. “==”的功能
“==”比較的是基本數據類型時,比較的是值,但是如果比較的是引用數據類型那一定是地址值;字符串當然是引用數據類型,只是他們的地址值因為構造函數的不同被存儲到串池和堆中,但始終也是不同的地址值;
如果非要比較字符串的值就使用equals方法;
三、常用查詢方法
方法 | 功能 | 示例 |
| 返回字符串長度 |
|
| 獲取指定索引的字符 |
|
| 查找子串首次出現的位置 |
|
| 查找子串最后一次出現的位置 |
|
| 判斷是否包含子串 |
|
| 判斷是否以指定字符串開頭 |
|
| 判斷是否以指定字符串結尾 |
|
四、字符串操作與修改
- 拼接與格式化
-
concat(String str)
:拼接字符串(效率低于+
或StringBuilder
)String.format(String format, Object... args)
:格式化字符串
String s = String.format("Name: %s, Age: %d", "Tom", 25);
//Name: Tom, Age: 25
說明符 | 作用 |
| 字符串 |
| 十進制整數 |
| 浮點數 |
| 換行符(平臺無關) |
| 布爾值( |
| 日期/時間(需搭配附加符號,如 |
| 轉義為普通 |
public class FormatExample {public static void main(String[] args) {// 混合使用多種格式String result = String.format("用戶: %s%n余額: %,.2f 元%n注冊日期: %tF","王五", 2500.5, new Date());System.out.println(result);}
}
// 用戶: 王五
// 余額: 2,500.50 元
// 注冊日期: 2023-10-05
-
String.join(delimiter, elements)
:用分隔符連接多個字符串
String.join("-", "2023", "08", "30"); // "2023-08-30"
- 子字符串提取
// 提取方法substring,一般有倆參數,第一個是開始的索引,第二個是結束的索引,含左去右
// 如果只有一個參數就是截取到末尾
// 注意,此方法并不影響原字符串,只是單純截取你索引中的字符串而已
String substr = "HelloWorld".substring(5); // "World"
String substr2 = "HelloWorld".substring(0,5); // "Hello"
- 替換操作
String s = "abac".replace('a', 'Z'); // "ZbZc"(替換所有匹配字符)
String s2 = "aabbaabb".replaceAll("aa", "XX"); // "XXbbXXbb"(正則替換)
String s3 = "aabbaabb".replaceFirst("aa", "XX"); // "XXbbaabb"
- 大小寫轉換
String upper = "hello".toUpperCase(); // "HELLO"
String lower = "JAVA".toLowerCase(); // "java"
- 去除空格
String trimmed = " text ".trim(); // "text"(去除首尾空格)
// JDK 11+ 新增 strip() 去除Unicode空格
- 分割字符串
String[] parts = "a,b,c".split(","); // ["a", "b", "c"]
// 正則分割:按數字分割
String[] arr = "a1b2c3".split("\\d+"); // ["a", "b", "c"]
五、字符串比較
- 內容比較
boolean isEqual = str1.equals(str2); // 區分大小寫
boolean isEqualIgnoreCase = str1.equalsIgnoreCase(str2); // 忽略大小寫
compareTo
方法
按字典序比較,返回差值:
"apple".compareTo("banana"); // 返回負數('a'在'b'前)
==
與equals
區別
==
比較對象地址,equals
比較內容。
String s1 = "abc";
String s2 = new String("abc");
s1 == s2; // false(地址不同)
s1.equals(s2); // true(內容相同)
六、其他工具方法
- 空字符串檢查
boolean isEmpty = str.isEmpty(); // JDK 6+
boolean isBlank = str.isBlank(); // JDK 11+(檢查空格或空)
- 重復字符串
String repeated = "abc".repeat(3); // JDK 11+ → "abcabcabc"