为什么在Java中,带前导符号(加号或减号)的数字在转换为BigDecimal时被视为有效数字?

为什么在Java中,带前导符号(加号或减号)的数字在转换为BigDecimal时被视为有效数字?,java,bigdecimal,Java,Bigdecimal,显然,以下表达式在Java中是有效的 int a = -0; int b = +0; 以下内容也是如此 Integer c = new Integer(-0); int d = Integer.parseInt("-0"); BigDecimal e = new BigDecimal("-0"); 然而,下列陈述是无效的 Integer f = new Integer("+0"); //Leading + sign. int g=Integer.parseInt("+0"); /

显然,以下表达式在Java中是有效的

int a = -0;
int b = +0;
以下内容也是如此

Integer c = new Integer(-0);
int d = Integer.parseInt("-0");
BigDecimal e = new BigDecimal("-0");

然而,下列陈述是无效的

Integer f = new Integer("+0");   //Leading + sign.
int g=Integer.parseInt("+0");    //Leading + sign.
它们都抛出
NumberFormatException

但是,以下带有
BigDecimal
的语句编译并运行时不会引发异常

BigDecimal bigDecimal = new BigDecimal("+0");  //Leading + sign.
为什么前导的
+
符号在这里与
BigDecimal
一起有效,而在Java中其他可用的数据类型中似乎没有这种情况?

根据,负号需要负号。但如果是正整数,就不需要加号

公共静态int-parseInt(字符串s)

字符串中的字符必须都是十进制数字,除了 第一个字符可以是ASCII减号“-”(“\u002D”)到 指示负值。返回结果的整数值, 就好像参数和基数10是作为 parseInt(java.lang.String,int)方法

那么对于构造器:

公共整数(字符串s)

字符串转换为int值的方式与parseInt方法对基数10使用的方式完全相同

真正的答案很可能是
newinteger(“+0”)
newbigdecimal(“+0”)
之间的不一致行为是其中一个设计错误的结果。不幸的是,当相关类被公开发布时,错误被“烤”了,Sun/Oracle不愿意修复它,因为:

  • 各自的实现符合各自的规范
  • 不一致性是一个相对较小的问题,需要简单的解决方法,并且
  • 修复它可能会破坏前后兼容性
  • (这个解释得到了@rlay3 found!!的评估部分的支持)


    注意,我没有考虑您的Java表达式示例。这是因为Java表达式语法和转换文本字符串的上下文完全不同,(IMO)您不应该期望它们的行为相同。(同样,您不应该期望字符串读取器对遇到的任何
    \
    字符执行特殊操作…)


    更新

    @ADTC观察到,他们确实在Java7中改变了这一点,并且
    Integer.parseInt
    现在接受了一个前导的
    +
    符号

    此增强对应的Java错误是。(如果您查看链接的bug,第一个bug似乎暗示更改已被后端口到OpenJDK6。)

    但是,Oracle在Java 7兼容性/升级文档中没有提到这一更改。。。这很奇怪,因为Sun之前因为兼容性问题拒绝了更改


    这一切都很奇怪

    至于为什么不支持前导加号,:“…如果我们更改Integer.parseInt的行为以允许前导加号(例如,BigInteger的字符串构造函数),Java平台库中的一些代码可能会中断,很可能我们在这方面并不是独一无二的。我强烈怀疑,如果我们在这么晚的时候更改建议的不兼容规范,我们的客户也会有代码被破坏。“Stephen C:)根据规范,这似乎是故意的。不是吗?不清楚是规范还是实现首先出现。。。或者最初的决定是否经过了适当的考虑,或者是否是在默认情况下做出的。“故意”和“错误”并不矛盾。事后看来,深思熟虑的行为通常被认为是错误。这在Java7中实际上发生了变化,现在接受了积极的迹象。