负char值JAVA

时间:2013-03-02 15:22:57

标签: java char int

为什么会发生以下情况:

char p = 0;
p--;
System.out.println(p);

结果 65535

为什么不给出编译错误或运行时异常? 我期待它作为字符不能是负面的。相反,它从倒置开始倒计时。 提前谢谢。

2 个答案:

答案 0 :(得分:16)

  

为什么不给出编译错误或运行时异常?

由于语言规范规定对基本类型的算术是模2^width,因此-1变为2^16-1char

the section on integer operations中,声明

  

内置整数运算符不以任何方式表示溢出或下溢。

所以禁止抛出异常。

对于所使用的postfix-decrement运算符,具体来说,其行为在15.14.3

中指定
  

否则,从变量的值中减去值1,并将差值存储回变量中。在减法之前,对值1和变量的值执行二进制数字提升(第5.6.2节)。如有必要,通过缩小基元转换(第5.1.3节)和/或在存储之前对变量类型进行装箱转换(第5.1.7节)来缩小差异。 postfix减量表达式的值是存储新值之前变量的值。

二进制数字促销将值和值1转换为int(因为此处的类型为char),因此您将中间结果-1作为{{1}然后执行缩小的基元转换:

  

有符号整数到整数类型T的缩小转换只会丢弃除n个最低位之外的所有位,其中n是用于表示类型T的位数。除了可能丢失有关幅度的信息之外数值,这可能导致结果值的符号与输入值的符号不同。

导致intchar(因为Java为其有符号整数类型指定了两个补码表示,在unary minus规范中明确说明):

  

对于整数值,否定与从零减去相同。 Java编程语言对整数使用二进制补码表示,并且二进制补码值的范围不对称,因此否定最大负数int或long会导致相同的最大负数。在这种情况下会发生溢出,但不会抛出异常。对于所有整数值x,-x等于(~x)+1。

对于超出范围结果的一般环绕行为,作为示例in the specification of the multiplication operator

  

如果整数乘法溢出,则结果是数学乘积的低阶位,如某些足够大的二进制补码格式所示。因此,如果发生溢出,则结果的符号可能与两个操作数值的数学乘积的符号不同。

类似的短语出现在整数加法的规范中,并且需要减法才能满足0xFFFF,因此出现溢出行为。

答案 1 :(得分:1)

因为这就是Java语言的定义方式。运行时不检查每个操作的边界(可能因为它非常昂贵)。它只是溢出或下溢。