为何Java的en-US DecimalFormat会将"1,2,3"解析为123?
为什么en-US地区的DecimalFormat解析"1,2,3"会得到123?
在使用en-US区域的DecimalFormat解析字符串"1,2,3"时,结果会是数字123,对应的测试代码如下:
import java.text.*; import java.util.Locale; public class Main{ public static void main(String[] args) throws ParseException { final String text = "1,2,3"; final int weirdResult = 123; final NumberFormat usDecimalFormat = DecimalFormat.getNumberInstance(Locale.US); final Number parsedNumber = usDecimalFormat.parse(text); if(parsedNumber.doubleValue() == weirdResult){ System.out.println(text + " is bizarrely parsed as " + weirdResult); } else { System.out.println(text + " is parsed as " + parsedNumber); } } }
运行后会输出:1,2,3 is bizarrely parsed as 123
原因解析
- 千位分隔符的定义:在en-US区域设置中,
DecimalFormat将逗号","定义为千位分组分隔符,用于格式化大数字(比如1,234表示1234)。 - 部分解析的特性:
DecimalFormat.parse()方法默认采用部分解析逻辑——它会从字符串开头尽可能解析出合法的数字内容,不会严格校验整个字符串是否完全符合格式规范。 - 对无效分隔符的处理:当解析到第二个逗号时,虽然它不符合千位分组“每三位一个分隔符”的规则,但
DecimalFormat不会直接抛出异常,而是将这个逗号视为无关的分隔符跳过,继续解析后面的数字字符。最终所有数字部分被拼接成123。
如何严格校验格式
如果需要确保整个字符串完全符合数字格式,可以通过ParsePosition跟踪解析位置,检查是否解析到了字符串末尾:
import java.text.*; import java.util.Locale; public class Main{ public static void main(String[] args) { final String text = "1,2,3"; final NumberFormat usDecimalFormat = DecimalFormat.getNumberInstance(Locale.US); ParsePosition pos = new ParsePosition(0); Number parsedNumber = usDecimalFormat.parse(text, pos); if (pos.getIndex() == text.length() && parsedNumber != null) { System.out.println(text + " is parsed as " + parsedNumber); } else { System.out.println(text + " is an invalid number format"); } } }
运行这段代码会输出:1,2,3 is an invalid number format,从而正确识别出不符合规范的字符串。
内容的提问来源于stack exchange,提问作者bruno
相关产品推荐
相关产品推荐

