Java String不可变,所有修改操作均返回新对象;replace()等方法不改变原字符串,需重新赋值;substring取左闭右开区间;运行时拼接用StringBuilder更高效;比较字符串内容须用equals()而非==。
Java 的 String 类不可变,所有“修改”操作实际都返回新对象——这是绝大多数字符串误用问题的根源。
replace() 没生效?因为 String 是不可变的,replace()、toUpperCase()、trim() 等方法从不修改原字符串,而是返回新实例。
String s = " hello ";
s.replace(" ", "");
s.trim();
System.out.println(s); // 输出仍是 " hello "String s = " hello ";
s = s.replace(" ", ""); // 注意这里赋值了
s = s.trim(); // 也必须赋值
System.out.println(s); // 输出 "hello"String result = s.trim().replace(" ", "").toLowerCase();substring() 的边界到底怎么算?substring(int beginIndex, int endIndex) 取的是 左闭右开区间,即包含 beginIndex,但不包含 endIndex。越界会抛 StringIndexOutOfBoundsException。
"abc".substring(1, 2) → "b"(索引 1 是 b,索引 2 是 c,但不包含)"abc".substring(1) → "bc"(单参数版本从指定位置到末尾)length() 当 endIndex 时别加 1,s.substring(0, s.length()) 才是完整字符串+ 还是 StringBuilder?编译期确定的字面量拼接(如 "a" + "b" + "c")会被 JVM 优化为单个常量;但运行时变量拼接(尤其循环中)用 + 会产生大量中间 String 对象,性能差。
str1 + str2 + "static" 可读性好,没问题StringBuilder sb = new StringBuilder();
for (String item : list) {
sb.append(item).append(",");
}
String result = sb.toString(); // 最后才转 Stringsb.toString(),它每次都会新建对象+ 做了部分优化,但逻辑复杂时仍推荐显式用 StringBuilder
equals() 和 == 到底该用哪个?== 比较的是引用地址,equals() 比较的是字符内容。除非明确要判断是否为同一对象(极少见),否则一律用 equals()。
if (s == "hello") { ... } // 错!可能因字符串池机制偶然成功,但不可靠if ("hello".equals(s)) { ... } // 推荐把字面量放前面,避免 s 为 null 时 NPE
equalsIgnoreCase(),别用 toLowerCase().equals()(创建多余对象)Objects.equals(a, b)(JDK 7+),自动处理 null字符串处理最易被忽略的其实是编码和 null 安全——new String(bytes, charset) 不指定编码名会依赖平台默认,split() 遇到 null 输入直接炸,这些地方没日志很难定位。