避坑指南 -- 【Java】当心 Integer.MAX_VALUE

MAX_VALUE

    /**
     * A constant holding the maximum value an {@code int} can
     * have, 2<sup>31</sup>-1.
     */
    @Native public static final int   MAX_VALUE = 0x7fffffff;

Integer.MAX_VALUE 是整型可以支持的最大数。用 8 位 16 进制表示,即 32 位 2 进制,最大值为 2^31-1

思考

因为 Integer 是有范围的 -2^31 ~ 2^31-1,所以当我们在 Integer 类型的变量达到最大值后 +1 ,会发生什么?

分析

测试代码

          System.out.println(Integer.MAX_VALUE);
          System.out.println(Integer.MAX_VALUE+1);
          System.out.println(Integer.MIN_VALUE);

打印结果分别为:2147483647 \ -2147483648 \ -2147483648 ,很明显 MAX_VALUE +1 后变成了 MIN_VALUE。

原理

在计算机中,数据都是以二进制表示的,运算都是基于补码进行。

了解原码、反码、补码(以 8 位平台,3、-5 为例)

首位为符号位, 0 表示正数 1 表示负数,码型转换不改变符号

原码:
 3 :0000 0011
-5 :1000 0101
反码: 正数的反码(原码) ,负数的反码(符号位不变,其他位取反)
 3 :0000 0011
-5 :1111 1010
补码: 正数的补码(原码) ,负数的补码(反码+1)
 3 :0000 0011
-5 :1111 1011

学会加减法

计算机中的加减法都是基于二进制补码进行的,例如计算 3+3 和 3-5

3+3 可以转化补码运算为  0000 0011 + 0000 0011  => 0000 0110
符号位是 0 为正数,其原码 = 补码 
(原码)0000 0110 => 2^2 +2^1 = 6
3 - 53 +-5)可以转化补码运算为 
0000 0011+1111 1011 =>1111 1110
符号位为 1 表示负数
(补码)1111 1110 =>(反码=补码-1)1111 1101=>(原码=反码取反)1000 0010 =>-(2^1) = -2
计算Integer.MAX_VALUE + 1

根据上面的计算原理,我们可以很轻松的得到

Integer.MAX_VALUE + 1 = (2^31-1) + 1 => (补)0111 1111 ... 1111 1111 + (补)0000 .... 0001
=> ()1000 0000 ... 0000 0000 =>(反)1111 1111 ... 1111 1111=>(原)1000 0000 ... 0000 0000 
=> -2^32 = Integer.MIN_VALUE

避坑指南

根据 MAX_VALUE + 1 = MIN_VALUE ,下面这段代码就可以说是丧心病狂了:

for(int i = 0;i<=Integer.MAX_VALUE;i++){
       //TODO
}

当 i 遍历达到最大之后,i++ 变为 MIN_VALUE,实现无限循环 ,直接跑路

在这里插入图片描述
但是大部分时候我们写这种逻辑是无心操作,比如我们循环条件中的最大值是通过参数传递过来的,如下:

public void doForeach(@NonNull Integer min_value,@NonNull Integer max_value){
	if(Integer.compare(min,max)>0){
        throw new RuntimeException("min_value must be less than or equal to max_value");
    }
    for(int i = min_value;i<=max_value;i++){
        //TODO
        System.out.println(i);
    }
}

这段代码看似没什么异常,但是却暗藏杀机,因为不确定传入的参数到底是什么,因此问题会很难复现,不仔细排查的话,很难料想到传进来的 max 会是个MAX_VALUE。
当然,知道原因的我们解决问题也很简单,把循环中的条件 i<=max_value 改为 i<max_value ,或者加一个判断就可以了

if(max==Integer.MAX_VALUE){
	throw new RuntimeException("max_value is out of range");
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mingvvv

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值