
String.substring(startIndex) 的行为到底是什么
String.substring(startIndex) 会从 startIndex 开始(包含该索引),一直截取到字符串末尾。它不关心后面有没有字符,只要 startIndex 在合法范围内(0 ≤ startIndex ≤ str.length()),就返回子串;如果超出范围,直接抛 StringIndexOutOfBoundsException。
常见错误:越界却没报错?其实是 startIndex == str.length()
很多人传入 startIndex = str.length() 后得到空字符串 "",误以为“出错了但被静默处理”——其实这是合法行为,JDK 明确定义:substring(length) 返回空串。真正容易踩的坑是:
startIndex 为负数 → 立即抛 StringIndexOutOfBoundsExceptionstartIndex > str.length() → 同样抛异常,不是返回 null 或空串对 null 字符串调用 substring() → 抛 NullPointerException,不是 StringIndexOutOfBoundsException
和 substring(startIndex, endIndex) 的关键区别
单参数版 substring(startIndex) 是双参数版的简化形式,等价于 substring(startIndex, str.length())。注意两点:
双参数版要求 startIndex ≤ endIndex,否则也抛 StringIndexOutOfBoundsException单参数版没有“结尾索引”概念,所以不存在 endIndex 的校验逻辑,只校验 <code>startIndex 是否越界性能上两者无实质差异,都是返回新字符串对象(Java 7u6 之后不再共享底层 char[])
实际使用时建议加一层安全封装
生产代码中直接裸调 substring() 风险高,尤其当 startIndex 来自外部输入或计算结果时。推荐先做边界归一化:
public static String safeSubstring(String str, int startIndex) { if (str == null) return null; int len = str.length(); if (startIndex < 0) startIndex = 0; if (startIndex > len) startIndex = len; return str.substring(startIndex);}
这样既避免异常中断,又让行为可预期:负数→从头开始,超长→返回空串。比到处写 try-catch 更轻量,也比每次手动判断更不易遗漏。
最常被忽略的是 null 检查——它不在 substring 的校验范围内,但线上 NPE 往往就栽在这儿。

评论(0)