最近在准备春招,刷到这样一道题“string 转换成 integer的方式及原理”,于是翻了翻源码,简单记录一下。
valueOf方法定义如下,可以看到方法中直接调用了parseInt,并默认使用十进制转换
public static Integer valueOf(String s) throws NumberFormatException {
return Integer.valueOf(parseInt(s, 10));
}
接下来详细看一下parseInt方法
public static int parseInt(String s, int radix) throws NumberFormatException
{
if (s == null) {
throw new NumberFormatException("null");
}
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; //存储计算结果
boolean negative = false; //正负标志
int i = 0, len = s.length();
int limit = -Integer.MAX_VALUE; //下界
int multmin; //中间计算过程中的一个下界
int digit; //存储中间计算结果
if (len > 0) {
char firstChar = s.charAt(0);
if (firstChar < '0') { // Possible leading "+" or "-"
if (firstChar == '-') {
negative = true;
limit = Integer.MIN_VALUE;
} else if (firstChar != '+')
throw NumberFormatException.forInputString(s);
if (len == 1) // Cannot have lone "+" or "-"
throw NumberFormatException.forInputString(s);
i++;
}
multmin = limit / radix;
while (i < len) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit(s.charAt(i++),radix);
if (digit < 0) {
throw NumberFormatException.forInputString(s);
}
if (result < multmin) {
throw NumberFormatException.forInputString(s);
}
result *= radix;
if (result < limit + digit) {
throw NumberFormatException.forInputString(s);
}
result -= digit;
}
} else {
throw NumberFormatException.forInputString(s);
}
return negative ? result : -result;
}
实现思路整理如下
判断字符串是否为null,若为null则直接抛出异常。
判断进制是否超出范围(小于2或大于36)
当字符串长度大于0时,先判断是否起于‘-’或者‘+’符号,并排除单符号情况
-
遍历字符串,利用Character.digit方法将char转换成int,并加到记录结果的result变量上。在这里进行了三次检查
if (digit < 0):非法字符,无法转换成int
if (result < multmin):为‘result *= radix;’语句做准备,避免溢出。这里multmin = limit / radix;
if (result < limit + digit):为‘result -= digit;’语句做准备,避免溢出。注意这里不能写成‘result- digit < limit;’
最后判断正负并返回结果
注意到一点,该方法在计算过程中所有数据均按照负数处理。个人觉得主要是简化了计算情况,同时只需要检查单边界。