发布于2026-07-10 阅读(0)
扫一扫,手机访问
先说结论:Scanner.useLocale() 是 Ja va 中一个容易被忽视但非常实用的方法。它的核心作用,就是让 Scanner 在解析数字时,按照指定区域的格式规则来识别小数点、千分位分隔符这些符号。换句话说,你只要给它一个 Locale,它就能自动读懂“3.14”和“3,14”之间的差异——当然,前提是这个 Locale 要设对。
那么,具体怎么用?本文从三个方面展开。

Scanner 在底层调用的是 DecimalFormat 和 NumberFormat 的解析规则。举个例子:
Locale.US(也是默认值)认为小数点是 .,千分位是 ,。所以 "3.14" 能被正常解析成 3.14,"3,141.59" 也能被正确识别为 3141.59。但如果你给它 "3,14",它会当成整数 3,因为逗号被当成千分位符号了。Locale.GERMAN 或 Locale.FRANCE 的规则是小数用 ,,千分位用 .。所以 "3,14" 可以正常解析,"3.14" 反而会抛出异常——因为点号在德语的语境里并不是小数点。来看一段代码:
Scanner sc = new Scanner("3,14\n42");
sc.useLocale(Locale.GERMAN);
double pi = sc.nextDouble(); // 成功读出 3.14
int n = sc.nextInt(); // 成功读出 42
需要提醒的是:假如输入是 "3.14" 但 locale 设成了 GERMAN,那 nextDouble() 会直接抛出 InputMismatchException,因为点号在德语环境中不被当作小数分隔符。
下面这张表汇总了常用区域的关键配置:
| 国家/地区 | 推荐 Locale | 小数分隔符 | 千位分隔符 | 示例数字字符串 |
|---|---|---|---|---|
| 美国、英国、澳大利亚 | Locale.US / Locale.UK |
. |
, |
"1234.56" |
| 德国、奥地利、瑞士德语区 | Locale.GERMAN / new Locale("de", "DE") |
, |
. |
"1.234,56" |
| 法国、比利时法语区 | Locale.FRANCE / new Locale("fr", "FR") |
, |
(空格) |
"1 234,56" |
| 巴西 | new Locale("pt", "BR") |
, |
. |
"1.234,56" |
几个实用的建议:
Locale.GERMAN 或 new Locale("de") 这样的形式,避免硬编码字符串 "de_DE",更安全也更清晰。pt_BR),用显式构造:new Locale("pt", "BR")。Locale.CHINA)默认小数点和美国一样是 .,所以不需要额外切换。Scanner 不会像人一样“猜”输入字符串里的小数点是点还是逗号。如果输入格式不固定,用户可能在某个字段里用了 .、另一个字段里用了 ,,那 useLocale() 就显得力不从心了。这时候的做法是:
next() 把原始字符串读出来;, 换成 .,然后用 Double.parseDouble() 来解析;NumberFormat 配合 ParsePosition 尝试多个 Locale。代码示例:
String raw = sc.next();
String normalized = raw.replace(',', '.'); // 粗略兼容:仅适用于无千位分隔符场景
double value = Double.parseDouble(normalized);
不过这种方法有隐患——如果输入是 "1.234,56",那替换后就成了 "1.234.56",完全错误。更健壮的方案是先判断字符串里哪个符号只出现一次且位于数字中间,然后再决定替换逻辑。不过,这已经超出 Scanner 的职责范围了。
看起来不复杂,但确实容易忽略。在跨区域数据处理场景下,这个小细节往往就是 bug 的源头。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8