scanner.uselocale() 用于指定数字解析的区域设置,使 nextdouble() 等方法按对应 locale 的小数/千位分隔符(如 us 用“.”、german 用“,”)正确解析,但不影响 next() 原始读取。

Scanner.useLocale() 的作用是让 Scanner 在解析数字(如 nextDouble()、nextInt()、nextBigDecimal() 等)时,按指定区域设置(Locale)的格式规则来识别小数分隔符、千位分隔符、正负号、货币符号等。关键在于:它只影响 Scanner 解析输入字符串为数值的内部行为,不改变输入源本身,也不影响 next() 或 nextLine() 的原始读取。
下面分三部分讲清楚怎么用它支持不同国家的小数点号(点或逗号):
用 useLocale() 指定 Locale 后,Scanner 自动识别对应小数分隔符
Scanner 内部使用 DecimalFormat 和 NumberFormat 的规则解析数字。例如:
-
Locale.US(默认):小数用.,千位用,→"3.14"✅,"3,141.59"✅,"3,14"❌(被当作整数 3) -
Locale.GERMAN或Locale.FRANCE:小数用,,千位用.→"3,14"✅,"3.141,59"✅,"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 | 小数分隔符 | 千位分隔符 | 示例数字字符串 |
|---|---|---|---|---|
| 美国、英国、澳大利亚 |
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" |
✅ 实用建议:
- 不要硬编码字符串
"de_DE",用Locale.GERMAN或new Locale("de")更安全; - 若需精确控制(如巴西用
pt_BR),显式构造:new Locale("pt", "BR"); - 中文环境(
Locale.CHINA)默认用.作小数点,和 US 一致,无需切换。
如何安全地处理混合格式或未知 locale 的输入
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 职责范围。
不复杂但容易忽略










