StringBuilder.reverse()能反转中文但不安全处理emoji等增补字符,因按char翻转可能拆散代理对;需备份原值,String不可变故无reverse()方法。

StringBuilder.reverse() 能直接反转中文或特殊字符吗
能,但前提是字符串本身编码正确、没被意外截断或乱码。Java 的 StringBuilder 基于 UTF-16,对 BMP 平面内的字符(包括常用汉字、英文字母、数字)反转完全可靠;遇到增补字符(如某些 emoji、古汉字),它按 char 单位翻转,可能把代理对(surrogate pair)拆开,导致乱码。
常见错误现象:"??abc".reverse() 可能输出乱码或异常显示,因为 ?? 是多个 Unicode 码点组成的序列,不是单个 char。
- 使用场景:纯 ASCII 或常规中文文本(如用户昵称、日志 ID)可放心用
reverse() - 若需安全处理 emoji、生僻字、数学符号等,应改用基于
codePointAt()的手动遍历,或先转为int[]码点再反转 -
StringBuilder不校验字符完整性,它只翻转内部char[]数组——这是性能优势,也是隐患来源
reverse() 后原 StringBuilder 被修改,怎么保留原始值
它就地修改,不返回新对象,也不保护原内容。调用 reverse() 后,原 StringBuilder 实例的内容已变,想留原始值,必须提前备份。
- 最简做法:
String original = sb.toString(); String reversed = sb.reverse().toString();—— 但此时sb已被改,original是备份,不是引用 - 更稳妥:需要多次反转或双向操作时,每次新建:
new StringBuilder(original).reverse().toString() - 别写
sb.reverse().reverse()来“恢复”,这多一次无效操作,且掩盖了意图;该备份就备份
和 String.valueOf(new StringBuffer(str).reverse()) 有啥区别
几乎没区别,但 StringBuffer 是线程安全的,加了同步开销;StringBuilder 不同步,快 10%–15%,日常单线程场景该用后者。
- 兼容性:两者
reverse()行为一致,返回自身引用,都修改原实例 - 性能影响:在循环内高频调用时,用
StringBuffer会轻微拖慢,尤其在高并发非共享场景下纯属浪费 - 错误倾向:有人误以为
StringBuffer“更稳”所以默认选它,其实只要不跨线程共享,StringBuilder更合适
为什么不能直接对 String 调用 reverse()
因为 String 是不可变类,没有 reverse() 方法。JDK 没给它加这个 API,设计上就拒绝原地修改。
- 常见错误现象:写
"hello".reverse()→ 编译报错:cannot resolve method 'reverse()' - 正确路径只有两条:转成
StringBuilder或StringBuffer再反转,或手写循环拼接(不推荐) - 别为了“链式”硬套:比如
String reversed = new StringBuilder(str).reverse().toString()就是标准解法,别省略中间步骤去造轮子
真正容易被忽略的是字符边界问题——不是所有“看起来是一个字”的东西,在 Java 里都是一个 char。处理用户输入、国际化文本前,先确认是否涉及增补字符;否则 reverse() 看似一行代码,结果却难以调试。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











