Java Integer.parseInt() 源码解析

//一般情况下,编程的基础类库支持2进制到36进制。
//s为传入准备转换为int类型的字符串,radix代表几进制
public static int parseInt(String s, int radix) throws NumberFormatException {

        //判断s是否为null
        if (s == null) {
            throw new NumberFormatException("null");
        }

        //判断进制是否在 2~36之间,比如10进制的数字,radix就填写10
        else if (radix < 2) {
            throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX");
        } else if (radix > 36) {
            throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX");
        }

        //不符合条件的进行排除
        else {
            boolean negative = false; //判断是否为负数,false代表正数,true代表负数
            int i = 0;//相当于一个指针,指向字符串Sring的位数进行检测
            int len = s.length();//字符串长度

            //limit 默认初始化为 最大正整数的负数 ,假如字符串表示的是正数,
            //那么result(在返回之前一直是负数形式)就必须和这个最大正数的负数来比较,判断是否溢出
            int limit = -2147483647;

            //如果传入字符串长度<=0,报异常退出
            if (len <= 0) {
                throw NumberFormatException.forInputString(s);
            }
            //如果>0,继续运行
            else {
                //取出字符串第一个字符
                char firstChar = s.charAt(0);
                //判断第一个字符是否是数字
                if (firstChar < '0') {
                    //如果第一个字符是负号
                    if (firstChar == '-') {
                        negative = true;        //判断正负字段转为true
                        limit = -2147483648;    //在负号的情况下,判断溢出的值就变成了整数的最小负数了
                    }
                    //如果第一个字符不是负号,也不是正号
                    else if (firstChar != '+') {
                        throw NumberFormatException.forInputString(s);    //无法转换,报异常退出
                    }
                    //如果string长度仅为1,第一个又不是数字,正负号,直接报异常退出
                    if (len == 1) {
                        throw NumberFormatException.forInputString(s);
                    }

                    ++i;//字符串第一个数字验证完毕,指针向右移动一位
                }


                //TODO: 下面是具体转换过程
                
                //这个是用来判断当前的 result 在接受下一个字符串位置的数字后会不会溢出
                int multmin = limit / radix;

                //存放最终返回结果的负数值,如果本身和就是负数,则就是原数
                int result;
                //根据i指针获取到每一个数值,存储到digit中
                int digit;
                for (result = 0; i < len; result -= digit) {
                    //获取到i指针所指向的字符,存放到dighit,之后i加一
                    digit = Character.digit(s.charAt(i++), radix);
                    //如果获取到的字符<0或者结果<最小值溢出,报异常退出
                    //result < multmin,说明result * radix 后还比 limit 小
                    if (digit < 0 || result < multmin) {
                        throw NumberFormatException.forInputString(s);
                    }


                    result *= radix;
                    if (result < limit + digit) {
                        throw NumberFormatException.forInputString(s);
                    }

                    /**
                     * 做一个假设,一开始输入一个数字字符串为123,那么对应的radix=10(因为是10进制的),digit = 123 / 10 计算得到的
                     * 第一次result *= radix  -->  result = 0 ;  result -= digit--> result = -1
                     * 第二次result *= radix --> result = -10; result -= digit --> result = -12
                     * 第三次result *= radix --> result = -12; result -= digit --> result = -123
                     * 此时,negative = false,则返回 -result,即最终结果为:123
                     *  */
                }

                //如果negative为true,说明返回的数为负数,直接返回result即可
                //如果negative为false,说明返回的数为正数,返回result的相反数
                return negative ? result : -result;
            }
        }
    }
}



 //  注:转换成负数来计算的主要原因是防止溢出,8位的正负数范围是 -128 ~ 127 所以,正数转换成负数不会溢出,最小负数转换成正数会溢出
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值