一、 不可变性 (Immutability):理解String的“灵魂”
在深入API之前,必须深刻理解 String
的不可变性。这是所有String
行为和性能考量的基石。
- 含义: 一旦一个
String
对象被创建,它的值就不能被改变。任何看起来“修改”了字符串的操作(如concat()
,replace()
),实际上都创建了一个新的String对象,而原字符串保持不变。 - 示例:
String str = "Hello";
str.concat(" World"); // 这个操作返回一个新字符串,但str本身未变
System.out.println(str); // 输出: Hello
str = str.concat(" World"); // 必须将新字符串的引用赋给str
System.out.println(str); // 输出: Hello World
二、 核心API实战:从“查”到“改”
1. 查询与判断 (Query & Check)
length()
: 获取字符串长度。
String s = "Java";
int len = s.length(); // len = 4
charAt(int index)
: 获取指定索引处的字符(索引从0开始)。
char c = s.charAt(1); // c = 'a'
// 注意:索引越界会抛出 StringIndexOutOfBoundsException
indexOf(String str)
/lastIndexOf(String str)
: 查找子串首次/最后一次出现的位置。找不到返回-1。
String text = "Hello, hello, world!";
int first = text.indexOf("hello"); // first = 7
int last = text.lastIndexOf("hello"); // last = 7 (如果只有一个)
startsWith(String prefix)
/endsWith(String suffix)
: 判断是否以指定前缀/后缀开始或结束。
String file = "document.pdf";
boolean isPdf = file.endsWith(".pdf"); // true
contains(CharSequence s)
: 判断是否包含指定的字符序列。
boolean hasJava = text.contains("Java"); // false (区分大小写)
isEmpty()
/isBlank()
(Java 11+):
isEmpty()
: 长度为0即为true (""
)。isBlank()
: 字符串为空或仅由空白字符(空格、制表符等)组成即为true (""
," "
)。推荐用于判空检查。
String empty = "";
String blank = " ";
empty.isEmpty(); // true
blank.isEmpty(); // false
blank.isBlank(); // true
2. 截取与分割 (Substring & Split)
substring(int beginIndex)
/substring(int beginIndex, int endIndex)
: 截取子串。注意:endIndex
是不包含的。
String s = "Programming";
String sub1 = s.substring(3); // "gramming" (从索引3到末尾)
String sub2 = s.substring(3, 7); // "gram" (索引3到6)
split(String regex)
/split(String regex, int limit)
: 根据正则表达式分割字符串,返回String[]
。
- 经典用法: 拆分CSV、解析路径。
String csv = "apple,banana,cherry";
String[] fruits = csv.split(","); // ["apple", "banana", "cherry"]
String path = "/home/user/documents/file.txt";
String[] parts = path.split("/"); // ["", "home", "user", "documents", "file.txt"] (注意第一个是空字符串)
- 陷阱:
split()
的参数是正则表达式!如果要按点号.
分割,必须转义:split("\\.")
,因为.
在正则中表示“任意字符”。