为什么DecimalFormat“。#”和“0#”在23.0上有不同的结果?

时间:2016-03-22 15:17:43

标签: java decimalformat

为什么java.text.DecimalFormat评估以下结果:

new DecimalFormat("0.#").format(23.0)        // result: "23"

new DecimalFormat(".#").format(23.0)         // result: "23.0"

我希望在两种情况下结果都是23,因为特殊字符#省略了零。主要特殊字符0如何影响分数部分? (尝试将其与javadoc中给出的BNF匹配/理解,但未能这样做。)

2 个答案:

答案 0 :(得分:7)

根据JavaDoc,第二种格式似乎无效,但无论如何它都会在没有错误的情况下解析。

 Pattern:
         PositivePattern
         PositivePattern ; NegativePattern
 PositivePattern:
         Prefixopt Number Suffixopt
 NegativePattern:
         Prefixopt Number Suffixopt
 Prefix:
         any Unicode characters except \uFFFE, \uFFFF, and special characters
 Suffix:
         any Unicode characters except \uFFFE, \uFFFF, and special characters
 Number:
         Integer Exponentopt
         Integer . Fraction Exponentopt
 Integer:
         MinimumInteger
         #
         # Integer
         # , Integer
 MinimumInteger:
         0
         0 MinimumInteger
         0 , MinimumInteger
 Fraction:
         MinimumFractionopt OptionalFractionopt
 MinimumFraction:
         0 MinimumFractionopt
 OptionalFraction:
         # OptionalFractionopt
 Exponent:
         E MinimumExponent
 MinimumExponent:
         0 MinimumExponentopt

在这种情况下,我希望格式化程序的行为不确定。也就是说,它可能产生任何旧的东西,我们不能依赖于任何方式的一致或有意义。所以,我不知道为什么你会得到23.0,但是你可以认为你在代码中应该避免它的废话。

<强>更新 我只是通过Java 7的DecimalFormat库运行调试器。代码不仅明确地表示&#39;。#&#39;是允许的,那里有一条评论(java.text.DecimalFormat:2582-2593),表示它已被允许,以及一个允许它的实现(第2597行)。这似乎违反了该模式记录的BNF。

鉴于这不是记录在案的行为,你真的不应该依赖它,因为它可能会在Java版本甚至库实现之间发生变化。

答案 1 :(得分:3)

以下源评论解释了".#"的相当不直观的处理方式。我的DecimalFormat.java文件(JDK 8)中的第3383-3385行有以下注释:

// Handle patterns with no '0' pattern character. These patterns
// are legal, but must be interpreted.  "##.###" -> "#0.###".
// ".###" -> ".0##".

似乎开发人员选择将".#"解释为".0##",而不是您所期望的("0.#")。