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

    技术2022-08-01  73

    方法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的边界判断不是很懂,希望有同学可以在评论里解惑

    Processed: 0.011, SQL: 9