一道Integer面试题引发的对Integer的探究
面试题: //在jdk1.5的环境下,有如下4条语句: Integer i01 = 59; int i02 = 59; Integer i03 =Integer.valueOf(59); Integer i04 = new Integer(59); 以下输出结果为false的是: A. System.out.println(i01== i02); B. System.out.println(i01== i03); C. System.out.println(i03== i04); D. System.out.println(i02== i04); 1.题目中提到了,是Jdk1.5的环境。 OK,我们新建一个项目,新建一个类,把代码复制进去。将Java Compiler设置为1.5. ?关于这个版本的问题稍后再谈。 2.这里有两个数据类型,int和Integer。 ? ?int为基本类型。 ? ?Integer为对象类型。Integer的类声明是这样的: public final class Integer extends Number implements Comparable<Integer> { ... } 1、Integer类是final的,不能被继承 2、Integer类实现了Comparable接口,所以可以用compareTo进行比较。 3、Integer继承了Number类,所以该类可以调用longValue、floatValue、doubleValue等系列方法返回对应的类型的值。 ?
3.题目中声明了三个Integer变量,i01,i03,i04.这三种声明方式有啥区别呢? ? 3.1 Integer i04 = new Integer(59); 做了什么?
看源码,这个构造函数是这样的: /** * The value of the {@code Integer}. * * @serial */ private int value; * Constructs a newly allocated { Integer} object that * represents the specified { int} value. * * @param value the value to be represented by the * { Integer} object. */ public Integer( value) { this.value = value; } new Integer(59)的这个操作,调用了构造函数,将59这个值,赋给了Integer的局部变量value。 ? 3.2 Integer i03 = Integer.valueOf(59); //这个 Integer.valueOf 方法又做了什么??
看Integer.valueOf源码: * Returns an { Integer} instance representing the specified * { int} value. If a new { Integer} instance is not * required,this method should generally be used in preference to * the constructor {@link #Integer(int)},as this method is likely * to yield significantly better space and time performance by * caching frequently requested values. * * This method will always cache values in the range -128 to 127,* inclusive,and may cache other values outside of this range. * * i an { int} value. * @return an { Integer} instance representing { i}. * @since 1.5 static Integer valueOf( i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } 这里,valueOf方法先判断传入参数的值,满足if 条件的话,则返回cache值。 否则 new 一个Integer 返回。这里的 if中的条件?IntegerCache.high=127,?IntegerCache.low=-128;从IntegerCache的类定义可以看出,IntegerCache里边定义了一个数组cache用来存储Integer对象,静态块里边完成了数组的初始化,存入了-128到127之间的Integer对象: static class IntegerCache {//这个类是 Integer 类的 静态内部类。看这个代码不难发现,在Integer加载之后这个内部类的cache数组里边就初始化了-128到127之间的值 int low = -128 high; final Integer cache[]; static { high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { int i = parseInt(integerCacheHighPropValue); i = Math.max(i,127); Maximum array size is Integer.MAX_VALUE h = Math.min(i,Integer.MAX_VALUE - (-low)); } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); } private IntegerCache() {} } 所以,对于I 这里传递的是59,所以返回的是cache里边的对象。 3.3 Integer i01 = 59;// 这句话又做了什么?
我们将源码产生的class文件反编译发现如下: 源码: public static void main(String[] args) ?
? 可以发现:Integer i01=59;在反编译过来之后是Integer.valueOf(59); 在用Integer 类型的i01和int类型的i02进行“==”比较的时候,反编译过来的是:i01.intValue()?== i02 这两个操作分别为 自动装箱 和自动拆箱。这个特性是在java1.5开始才有的。所以第一点中提到了jdk版本为1.5. ? 如果我们在eclipse/myeclipse 中将java compiler设置成1.5以下的就会无法通过编译: Type mismatch: cannot convert from int to Integer ? ? 通过上面的分析,这题就不难得出答案了。 i01 == i02 等价于 ?i01.intValue()==i02 ?两个值的比较59==59 ? -->true; i01 == i03 由于 59在-128到127之间,所以,i01和i03的赋值操作返回的是同一个对象。都是从chche中返回的同一个对象,对象地址相同 ? true; i03 == i04 i03是来自缓存值,i04是新new的对象 ,二者不是同一个对象,所以false。 i02 == i04 和第一个类似,true。 ? (编辑:北几岛) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |