charAt只能获取单个字符,不能截取子串;截取子串必须使用substring,其endIndex为不包含的右边界。

charAt 方法只能获取单个字符,不能截取子串
charAt 是 String 类的实例方法,作用是返回指定索引处的 char 值(16 位 Unicode 字符),不是截取字符串的工具。它不生成新字符串,也不支持范围操作。
常见错误现象:
想取第 3 到第 7 位子串却写成 str.charAt(2).charAt(3).charAt(4)... —— 这会直接编译失败,因为 char 没有 charAt 方法。
- 索引从 0 开始,
str.charAt(0)是首字符 - 越界会抛出
StringIndexOutOfBoundsException - 如果目标是“取某一位”,
charAt正确;如果目标是“取一段”,该用substring
要截取子串,请用 substring 而不是 charAt
Java 中截取连续字符段必须用 substring。它有两个重载版本:substring(int beginIndex) 和 substring(int beginIndex, int endIndex)。
注意:endIndex 是**不包含**的右边界(左闭右开),这点和 Python 的切片一致,但容易被误以为是“长度”或“包含末位”。
立即学习“Java免费学习笔记(深入)”;
-
"hello".substring(1, 4)→"ell"(索引 1、2、3) -
"hello".substring(2)→"llo"(从索引 2 到末尾) - 若
beginIndex == endIndex,返回空字符串"" - 索引越界同样抛
StringIndexOutOfBoundsException
charAt 和 substring 的性能与使用场景差异
charAt 是 O(1) 操作,底层直接访问内部 char[] 数组;substring 在 Java 7u6 之后也是 O(1),因为返回的新字符串共享原字符串的字符数组(仅维护自己的 offset 和 count)。但要注意:如果原字符串极大,而你只取其中很小一段,长期持有这个子串可能导致原大数组无法被 GC。
- 只读单个位置?用
charAt—— 简洁、无对象分配 - 需要新字符串对象?必须用
substring(哪怕只取一个字符,如s.substring(5, 6)) - 频繁按索引查字符 + 拼接?考虑先转为
char[],避免重复边界检查
容易忽略的边界问题:空字符串和负索引
对空字符串调用 charAt(0) 或 substring(0, 0) 都合法(后者返回 ""),但 charAt(0) 会抛异常。负索引在任何情况下都不允许,JVM 不做自动归正。
-
"".charAt(0)→StringIndexOutOfBoundsException -
"".substring(0, 0)→""(合法) -
s.charAt(-1)或s.substring(-1, 2)→ 直接抛异常,不会“倒序取” - 安全做法:使用前先判断
s != null && !s.isEmpty(),再检查索引范围
charAt 能返回字符串”,结果类型不匹配或逻辑错位。真正要拼接、传参、存库的,几乎总是需要 String 类型,这时候绕不开 substring。











