Java substring生成新字符串,不修改原串;单参数从beginIndex到末尾,双参数取[beginIndex,endIndex)区间;需防越界、null、emoji代理对及语义化截取风险。

Java 的 substring 方法用来从原字符串中提取一段连续的字符,生成一个**全新的字符串对象**。它不修改原字符串(String 不可变),核心是按索引位置操作,但必须注意“左闭右开”和边界安全。
两种基本用法
1. 单参数:substring(int beginIndex)
从指定下标开始,一直取到字符串末尾(包含 beginIndex 位置的字符)。
- 例如:
"Java8".substring(2)→"va8"(下标 2 是 'v') - 合法范围:0 ≤ beginIndex ≤ 字符串长度;等于长度时返回空字符串 ""
2. 双参数:substring(int beginIndex, int endIndex)
截取 [beginIndex, endIndex) 区间,即包含起始位置,**不包含**结束位置的字符。
- 例如:
"Java8".substring(1, 4)→"ava"(取下标 1、2、3) - 合法条件:0 ≤ beginIndex ≤ endIndex ≤ 字符串长度
常见错误与规避方式
直接硬写索引容易抛 StringIndexOutOfBoundsException,尤其在长度不确定或含 emoji 时:
- 别写
s.substring(0, -1)—— 负索引非法;要去掉末尾字符,改用s.substring(0, Math.max(0, s.length() - 1)) - 用
indexOf或lastIndexOf定位后再截取更安全,比如取冒号前内容:s.substring(0, s.indexOf(':')),但要先判断indexOf是否返回 -1 - 若字符串可能为 null,务必前置判空:
if (s != null && !s.isEmpty()) { ... }
处理 Unicode 补充字符(如 emoji、生僻汉字)
String 内部用 UTF-16,某些字符占两个 char(代理对)。按普通索引切可能只取到高代理位,导致乱码或后续方法异常。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 不推荐:
s.substring(0, 1)截取 "??" —— 可能只拿到 '?' 的高位 - 推荐方案:
• 使用BreakIterator按字符边界切分
• 或引入 Apache Commons Lang:StringUtils.substring(s, 0, 1)(内部已处理代理对)
• 纯 JDK 方式:用s.codePoints()流操作,按码点计数
替代思路:按内容而非索引截取
当目标是“取某个符号之前”“去掉后缀”等语义化需求时,正则或内置方法往往更稳:
立即学习“Java免费学习笔记(深入)”;
- 取第一个冒号前的内容:
s.replaceFirst(":(.*)", "") - 去路径最后一级(如 "/a/b/c.txt" → "/a/b"):
s.replaceAll("^(.*?)/[^/]*$", "$1") - 简单去后缀(如 ".txt"):
s.endsWith(".txt") ? s.substring(0, s.length() - 4) : s

















