本帖最后由 田啸 于 2012-3-3 00:18 编辑
感觉首先你对== 和equals 不是很清楚,先看看 == 和equals 的区别:
== 在操作数是基本数据类型时,是比较值是否相等,在操作数是引用类型时,比较的是是否指向堆中同一个对象。
equals是object的普通方法,object是所有类的基类,不同的类,重写equals的方法不同,基本数据类型当然没这个方法,所以会提示你i,j为基本类型的错误
然后看下Integer的equals:
01.public boolean equals(Object obj) {
02. if (obj instanceof Integer) {
03. return value == ((Integer)obj).intValue();
04. }
05. return false;
06. }
自动装箱其实就是编译器编译的时候,自动帮你把int变成Integer对象,调用的是Integer的静态方法valueOf(),看反编译过来的代码就可以看出:
01.public static Integer valueOf(int i) {
02. if(i >= -128 && i <= IntegerCache.high)
03. return IntegerCache.cache[i + 128];
04. else
05. return new Integer(i);
06. }
当你调用这个方法,把int变成Integer的时候,是有规则的,当你的int的值在-128-IntegerCache.high(127) 时,返回的不是一个新new出来的Integer对象,而是一个已经缓存在堆中的Integer对象,(我们可以这样理解,系统已经把-128到127之间的Integer缓存到一个Integer数组中去了,如果你要把一个int变成一个Integer对象,首先去缓存中找,找到的话直接返回引用给你就行了,不必再新new一个)。
包装类的==操作在没有遇到算术运算的情况下,不会自动拆箱:
当==2边是包装类的时候,其实包装类就是对象,比较的是2个对象引用是否指向同一个对象,如果2边有一个是基本数据类型的话,那么就是比较值大小,这个优先级更高,既然是比较值大小,那么自然另一边的包装类就要拆箱成基本类型进行比较值大小了)
当==2边是基本数据类型,那就会直接比较大小,因此就不会自动装箱
|