
StringTokenizer 已被标记为遗留类,不推荐新代码使用
Java 官方从 JDK 1.4 就明确建议用 String.split() 或 java.util.Scanner 替代 StringTokenizer。它不支持正则表达式、无法跳过空字段、不能处理连续分隔符的语义差异,且 API 设计僵硬——比如构造时就固定分隔符,后续无法动态调整。
除非维护老项目(JDK 1.0–1.3 风格代码),否则别主动选它。现代写法更简洁、行为更可控。
String.split() 怎么正确处理连续分隔符和空字符串
String.split() 默认会丢弃结尾的空字符串,但保留中间的——这常导致数组长度出人意料。比如 "a,,b,".split(",") 返回长度为 3 的数组:["a", "", "b"],末尾的空串被切掉了。
- 要保留所有分割结果(包括开头、中间、结尾的空串),传入负数限制参数:
"a,,b,".split(",", -1)→["a", "", "b", ""] - 想彻底忽略所有空字段?得自己过滤:
Arrays.stream(str.split(",")).filter(s -> !s.isEmpty()).toArray(String[]::new) - 分隔符含特殊正则字符(如
.、|、*)必须转义:str.split("\."),不是str.split(".");
为什么 StringTokenizer 在多线程或循环中容易出错
StringTokenizer 是有状态的:它内部维护一个游标位置,调用 nextToken() 会推进该位置。一旦在循环里重复使用同一个实例,或者多个线程共享它,结果完全不可预测。
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
立即学习“Java免费学习笔记(深入)”;
- 每次解析新字符串,都该新建一个
StringTokenizer实例,别复用 - 它没有重置方法,也没办法“倒带”,不像
Scanner可以用useDelimiter()动态切换 - 它的
hasMoreTokens()和nextToken()不是原子操作,多线程下可能抛NoSuchElementException
替代方案对比:split() vs Scanner vs Pattern
简单按固定字符切?用 String.split() 最轻量。需要逐个读取、支持跳过空白或混合类型解析?用 Scanner 更自然。要复用分隔逻辑或做复杂匹配?直接上 Pattern.compile() + Matcher。
-
String.split():适合一次性全量切分,底层用Pattern,但无状态、不可中断 -
Scanner:适合流式读取,可设useDelimiter("\s+")跳过多余空白,还能直接nextInt()、nextDouble() -
Pattern:当分隔逻辑需复用(如日志行解析),编译一次多次matcher(input).replaceAll()或find()
真正难的不是怎么切,而是想清楚:你到底要的是「切片」还是「解析」?前者用 split(),后者往往得自己定义 token 规则。

















