为什么带有char的循环因为它的索引无限循环?

Pho*_*nix 3 java loops char

这个循环将无限期地继续:

char a = 100;
for(a=100; a>=0;--a)
    System.out.println(a);
Run Code Online (Sandbox Code Playgroud)

是否会发生这种情况,因为a被提升为算术运算的int值,并从16位char值扩展到32位,因此将始终保持正值?

old*_*inb 8

它确实会无限循环 - 你说的理由很接近.这是因为a不能代表任何数量并不满足a >= 0- char是无符号.算术下溢在Java中是明确定义的,并且没有指示.请参阅规范的以下相关部分.

  • §4.2.2

    整数运算符不以任何方式指示上溢或下溢.

    这意味着除了比较值之外没有溢出/下溢的迹象......例如,如果a<= --a,那么这意味着发生了下溢.

  • §15.15.2

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

    因此,我们可以看到这里有两个主要步骤:二进制数字促销,然后是缩小的初始转换.

  • §5.6.2

    应用扩展基元转换(第5.1.2节)来转换由以下规则指定的一个或两个操作数:

    • 如果任一操作数是类型double,则另一个操作数转换为double.
    • 否则,如果任一操作数是类型float,则另一个操作数转换为float.
    • 否则,如果任一操作数是类型long,则另一个操作数转换为long.
    • 否则,两个操作数都将转换为类型int.

    我们可以看到递减表达式a被视为处理为int,从而执行扩展转换.这允许它表示值-1.

  • §5.1.3

    缩小的原始转换可能丢失关于数值的总量值的信息,并且还可能失去精度和范围.

    ...

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

    仅保留n个最低阶位意味着仅保留int表达式的最低16位a - 1.由于-10b11111111 11111111 11111111 11111111在这里,只有较低的0b11111111 11111111保存.由于char是无符号的,所有这些位都对结果有贡献,给出65535.

注意到这里有什么?从本质上讲,这意味着Java整数算法是模块化的 ; 在这种情况下,模数是2 ^ 1665536,因为char它是16位数据类型.-1(mod 65536)≡65535,因此减量将回绕.