Integer.parseInt(String s ,int radix) 详解+源码

方法parseInt(String s,int radix)的目的是输出一个十进制数,输入参数“String s”,后面“int radix”代表该数字的进制,通过该方法将指定进制的数字转化成10进制输出返回。

比如:parseInt(1010,2)
意思就是:输出2进制数1010在十进制下的数.
更直白地说:parseInt(String s,int radix)就是求“int radix”进制数“String s”的十进制数是多少。

我们平时用的Integer valueOf(String s),调用的实际就是Integer.parseInt(“123”,10);

花了些时间看了该方法的源码,对源码做了一些解析。当然也有一些细节不是很懂

    public static int parseInt(String s, int radix)
            throws NumberFormatException
    {
        /*
         * WARNING: This method may be invoked early during VM initialization
         * before IntegerCache is initialized. Care must be taken to not use
         * the valueOf method.
         */

        //判断字符串是否为空,为空抛异常
        if (s == null) {
            throw new NumberFormatException("null");
        }
        //进制的范围为MIN_RADIX(2)~MAX_RADIX(36)之间,不在这个范围内的,抛异常
        if (radix < Character.MIN_RADIX) {
            throw new NumberFormatException("radix " + radix +
                    " less than Character.MIN_RADIX");
        }

        if (radix > Character.MAX_RADIX) {
            throw new NumberFormatException("radix " + radix +
                    " greater than Character.MAX_RADIX");
        }

        int result = 0;   //结果数值,初始化值为0
        boolean negative = false; //是否为负数,初始化为false,代表非负数
        int i = 0, len = s.length();
        int limit = -Integer.MAX_VALUE;
        int multmin;//用于在添加下一位数字的前判断是否溢出的值(下面有计算)
        int digit;  //当前需要追加的数字

        //字符串中的是否有符号,没有则抛错
        if (len > 0) {
            char firstChar = s.charAt(0);
            //拿到第一个字符,与‘0’比较,如果小于‘0’,显然非数字。这时判断是否是‘-’号,如果是,将negative置为true,然后设置limit = Integer.MIN_VALUE;
            if (firstChar < '0') { // Possible leading "+" or "-"
                if (firstChar == '-') {
                    negative = true;
                    limit = Integer.MIN_VALUE;
                    //接着首字节既不是‘-’号,又不是‘+’号,还是小于‘0’,那么非数字和也非性质符号,所以抛出NumberFormatException
                } else if (firstChar != '+')
                    throw NumberFormatException.forInputString(s);

                //如果只有一个符号,没有数字,显然也不对,所以后续对s.length == 1情况抛出NumberFormatException
                if (len == 1) // Cannot have lone "+" or "-"
                    throw NumberFormatException.forInputString(s);
                //这里i++是因为如果首位不是数字是符号的话,在后续的循环追加数字是不需要第首位内容的
                i++;
            }
            //根据进制,调整int的边界
            multmin = limit / radix;

            //开始循环追加数字,逐步的获取数字
            while (i < len) {
                //将字符转为为对应进制的整数,如果该字符不是进制内的就返回-1.例如输入的字符有9,但是进制是2,那么就不符合,会返回-1
                digit = Character.digit(s.charAt(i++),radix);
                //字符不符合进制,抛异常
                if (digit < 0) {
                    throw NumberFormatException.forInputString(s);
                }

                if (result < multmin) {
                    throw NumberFormatException.forInputString(s);
                }
                //循环结算结果,result的计算建议大家自己打断点看一下循环计算过程。
                result *= radix;
                if (result < limit + digit) {
                    throw NumberFormatException.forInputString(s);
                }
                result -= digit;
            }
        } else {
            throw NumberFormatException.forInputString(s);
        }
        //判断是否是负数,返回对应结果
        return negative ? result : -result;
    }

源码注释写的比较多了,再补充一些方法的说明
char firstChar = s.charAt(0);
返回的是ASCII码的值,比如你输入5,firstchar对应的值是53

Character.digit(s.charAt(i++),radix);
方法的说明:字符类型转化为radix进制的整数.比如radix为10就转为10进制的,16就是16进制的.如果该字符不是进制内的就返回-1。所以在在代码中会对返回值是否<1做判断并做对应的处理

result的计算,在循环里,跟我们平时的进制计算公式做了一个数学的转换。比如5*163+2*162+3*161+5*160 可以转化为((5*16+2)*16+3)*16+5,在对应到这个循环的步骤里,应该就比较清晰了

关于result < limit + digit的边界判断不是很懂,希望有同学可以在评论里解惑

你可能感兴趣的:(java)