最近在面试的时候,有好几个面试官问了我 Integer.valueOf 这个方法。这个方法之前确实没研究过,所以专门记录一下。
Integer.valueOf方法有三个重载,分别是
- Integer.valueOf(String s, int radix)
- Integer.valueOf(String s)
- Integer.valueOf(int i)
前两个方法都会调用到最后这个方法来,所以直接看参数最多的一个就好了。
//首先解释一下两个参数的含义,第一个参数是待转换的字符串,第二个参数为字符串的进制。
public static Integer valueOf(String s, int radix) throws NumberFormatException {
return Integer.valueOf(parseInt(s,radix));
}
也就是如果我们需要转换10进制的 '123' 的话,输入就是 ("123",10), 如果需要转换2进制的数字,输入就是("10101101",2)
进入方法之后首先会进入parseInt方法。这个方法会将输入转换为int结果。首先来分析一下:
public static int parseInt(String s, int radix)
throws NumberFormatException
{
//检验一下是否为空
if (s == null) {
throw new NumberFormatException("null");
}
//校验一下进制是否在范围内,最小为2进制,最大为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");
}
//下面运算的时候全部先转为负数运算,这样方便判断溢出
boolean negative = false;
int i = 0, len = s.length();
int limit = -Integer.MAX_VALUE;
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, radix);
}
if (len == 1) { // Cannot have lone "+" or "-"
throw NumberFormatException.forInputString(s, radix);
}
i++;
}
//先计算好中间值
int multmin = limit / radix;
int result = 0;
while (i < len) {
//Character.digit方法作用就是将字符转换为数字
int digit = Character.digit(s.charAt(i++), radix);
//此处有两个判断,1.如果字符非法,报异常
//2.如果result在没有进位时便超过了multmin,那么进位后必然溢出,报异常
if (digit < 0 || result < multmin) {
throw NumberFormatException.forInputString(s, radix);
}
result *= radix;
//此处还有一个溢出判断,判断result添加digit后是否会溢出,如果溢出报异常
if (result < limit + digit) {
throw NumberFormatException.forInputString(s, radix);
}
result -= digit;
}
//判断是否为负数,将实际结果转变过来
return negative ? result : -result;
} else {
throw NumberFormatException.forInputString(s, radix);
}
}
整个 parseInt 方法逻辑还是比较清晰的。理解一下应该没啥难度。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
在转换为int之后,Integer类还会对int进行一个对象的包装。这个地方涉及到Integer的缓存。在jvm启动的时候,默认情况会将-128 - 127中间的数字先缓存在jvm中,这样用到的话便可以直接调用。
那么到这儿的话Integer.valueOf方法解析到这儿就完了。
说实话看了一遍还是不太理解为啥面试要问这个(^_^)v