5

显而易见,以下表达式在 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 中可用的其他数据类型似乎并非如此?

4

2 回答 2

4

根据文档,负号需要减号。但如果它是一个正整数,则不需要加号。

public static int parseInt(String s)

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

然后对于构造函数:

public Integer(String s)

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

于 2012-10-22T02:23:59.170 回答
3

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

  1. 各自的实现确实符合各自的规范,
  2. 通过简单的解决方法,不一致是一个相对较小的问题,并且
  3. 修复它可能会破坏向前和向后的兼容性。

(这个解释得到了@rlay3 发现的Java Bug #4296955的评估部分的支持!!)


请注意,我已将您的 Java 表达式示例排除在考虑范围之外。这是因为 Java 表达式语法和转换文本字符串的上下文完全不同,以至于 (IMO) 您不应该期望它们的行为相同。\(同样,你不应该期望字符串阅读器对它遇到的任何字符做一些特殊的事情......)


更新

@ADTC 观察到他们实际上确实在 Java 7 中改变了这一点,并且Integer.parseInt现在确实接受了一个领先的+标志。

此增强功能的相应 Java 错误是#5017980。(如果您查看链接的错误,第一个错误似乎暗示该更改已被反向移植到 OpenJDK6。)

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

这一切都相当奇特......

于 2012-10-22T02:56:21.990 回答