之前在面试人人车问的我的第一个问题就是
面试官:“我定义一个Integer i=300 再定义一个Integer i2=300,如果使用i==i2返回true还是false”。
一问完这个当时就蒙了,以前也没用过这个,当时我说的是什么相当于创建对象,==比较的是地址,所以返回false
面试官:“你这个说错了,应该是true”
当时也没太在意,今天偶然间看知识点时看到了这个点,没有当初想象那么简单
Integer i=100;
定义一个Integer等同于的是:
Integer i1=Integer.valueOf(100);
我们看一下valueOf中到底干了什么?
public static Integer valueOf(int i) {
return i >= -128 && i <= Integer.IntegerCache.high ? Integer.IntegerCache.cache[i + 128] : new Integer(i);
}
如果我输入了一个[-128,127]之间的数,则直接从从缓存中获取,就是为了减少对象创建和节省内存,否则,不在这个范围内的数则会重新创建Integer对象。
我们来测试一下区别:
public static void main(String[] args) {
Integer i1=Integer.valueOf(100);
Integer i2=Integer.valueOf(100);
System.out.println(i1==i2);
Integer i3=Integer.valueOf(300);
Integer i4=Integer.valueOf(300);
System.out.println(i3==i4);
}
打印结果:
true
false
i1跟i2是相同的,因为它是在[-128,127]之间,直接从缓存中获取,并没有创建新对象。
i3跟i4是不同的,因为他们没有在范围内,则会重新创建Integer对象,i3和i4是两个不同的对象。
我们可以再仔细看看他的这些代码:
public static Integer valueOf(int i) {
return i >= -128 && i <= Integer.IntegerCache.high ? Integer.IntegerCache.cache[i + 128] : new Integer(i);
}
public static Integer valueOf(String s, int radix) throws NumberFormatException {
return parseInt(s, radix);
}
public static Integer valueOf(String s) throws NumberFormatException {
return parseInt(s, 10);
}
源码中有三个方法的重载,可以看出另外两个方法中实际调用的parseInt()。
parseInt()就是将字符串类型转换成整数类型。
//一般我们常用这个方法
//第一个参数是字符换,第二个是进制数(支持2-36之间的进制)
public static int parseInt(String s, int radix) throws NumberFormatException {
if (s == null) {
throw new NumberFormatException("null");
} 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 {
//如果在2-36之间
boolean negative = false;//判断是否为负数
int i = 0;
int len = s.length();
int limit = -2147483647;
if (len <= 0) {
throw NumberFormatException.forInputString(s);
} else {
char firstChar = s.charAt(0);
//第一个字符
if (firstChar < '0') {
if (firstChar == '-') {
negative = true;
limit = -2147483648;
} else if (firstChar != '+') {
throw NumberFormatException.forInputString(s);
}
if (len == 1) {
throw NumberFormatException.forInputString(s);
}
++i;
}
//否则在这里
//计算multmin 值 ,multmin = -214748364 负数跟整数的limit是不同的
int multmin = limit / radix;
int result;
int digit;
//开始循环追加数字,比如输入“123” 10进制数
for(result = 0; i < len; result -= digit) {
digit = Character.digit(s.charAt(i++), radix);
//判断,在追加后一个数字前,判断其是否能能够在继续追加数字,比如multmin =
//123,那么再继续追加就会变为123*10+下一个数字,就会溢出
if (digit < 0 || result < multmin) {
throw NumberFormatException.forInputString(s);
}
result *= radix;
//用于判断下一个准备追加的数字是否可以追加,比如result现在是120,那么,如
//果digit是5,那么追加后就会变为125,已经超过123的限制了,注意这里是
//limit而不是multmin
if (result < limit + digit) {
throw NumberFormatException.forInputString(s);
}
}
return negative ? result : -result;
}
}
}
//很少用到
public static int parseInt(CharSequence s, int beginIndex, int endIndex, int radix) throws NumberFormatException {
...
}
//默认十进制
public static int parseInt(String s) throws NumberFormatException {
return parseInt(s, 10);
}
源码看到这里我也没怎么看明白怎么处理的,主要是了解一下java中的基础知识,弥补缺漏。