一段只有8行的Java代码,却让无数程序员陷入困惑。循环条件明明是i < 10,循环体里却在执行i--——数字越来越小,怎么可能满足终止条件?但运行结果清清楚楚:程序正常结束,最终输出"i" value is 127。
问题的答案藏在数据类型的边界里。变量i被声明为byte类型,而在Java中,byte只能存储-128到127之间的整数。循环从0开始递减,一路经过-1、-2……直到触及下限-128。下一步要变成-129时,发生了整数溢出(integer overflow),数值直接跳转到上限127。
![]()
127当然不小于10。循环条件瞬间失效,程序退出。整个过程恰好执行256次迭代,输出从0到-128,再从127倒序打印——虽然代码里写的是递减,但溢出后的那个127只参与条件判断,并未进入打印语句。
![]()
这个案例暴露了强类型语言中一个容易被忽视的陷阱:算术运算的语义与类型宽度紧密绑定。开发者习惯了int的宽广范围,偶尔切换到byte或short时,溢出行为可能完全颠覆直觉。更隐蔽的是,Java的整数溢出不会抛出异常,而是静默回绕,这让bug更难被发现。
类似的问题也出现在其他场景。比如用byte计算哈希值、处理图像像素、或者实现环形缓冲区时,如果假设"递减总会得到更小的数",就可能埋下逻辑漏洞。现代Java虽然提供了Math.addExact等带溢出检测的方法,但默认的运算符行为仍保持与早期版本兼容。
![]()
这段代码在社交媒体上流传时,经验丰富的工程师往往第一反应是"死循环",直到被提醒注意类型声明。它成了一个经典的面试题:考察的不是语法知识,而是对计算机底层表示的理解——补码编码、固定位宽、以及语言规范中的明确定义。
最终输出的那个127,是-128的"邻居"在二进制层面的直接映射。理解这一点,比记住答案更有价值。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.