Integer、int ==和equals问题
重点:自动装箱或拆箱在-128-127值,会从常量池中直接获取,不用创建新的对象
Integer a = new Integer(200);
Integer b = new Integer(200);
Integer c = new Integer(2);
Integer d = new Integer(2);
System.out.println("a == b " +(a == b));
System.out.println("c == d " +(c == d));
System.out.println("a == b " +a.equals(b));
System.out.println("c == d " +c.equals(d));
使用new关键字 的时候都会在堆内存中申请一块空间,存放相应的对象的值,然后在栈中存放这块内存的引用。所以a == b, c == d;返回都为false;
包装类重写Object类中的equals方法,重写后只比较数值,所以 a.equals(b)、c.equals(d)返回的都是true;
Integer e = 200;
Integer f = 200;
Integer q = 2;
Integer p = 2;
System.out.println("e == f " + (e == f));
System.out.println("q == p " +(q == p));
System.out.println("e == f " +e.equals(f));
System.out.println("q == p " +q.equals(p));
用int给Integer赋值的这条语句,从jdk1.5开始能这么做了,因为从这个版本开始,java引入了自动装箱、自动拆箱机制。这几行就是一个自动装箱的过程,相当于:
Integer c = Integer.valueOf(200);
在Integer类中,valueOf方法是这么实现的:
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
上面这段代码首先规定了一个范围,默认是-128-127之间,如果参数中的i在这个范围之内,则返回一个数组中的内容,如果不在这个范围,则new一个新的Integer对象并返回。查看Integer类的源码可以发现,这个数组里面缓存了基本类型-128-127之间的Integer对象。所以 e ==f 返回false,q == p返回true。equals同上
Integer a = new Integer(200);
Integer e = 200;
Integer c = new Integer(2);
Integer q = 2;
System.out.println("a == e " + (a == e));
System.out.println("c == q " + (c == q));
System.out.println("a == e " + a.equals(e));
System.out.println("c == q " + c.equals(q));
使用关键字new 都会在堆中创建一个新的空间,所以a == e、"c == q 返回的都是false,equals同上。
Integer a = new Integer(200);
Integer e = 200;
int x = 200;
Integer c = new Integer(2);
Integer q = 2;
int y = 2;
System.out.println("a == x " + (a == x));
System.out.println("e == x " + (e == x));
System.out.println("c == y " + (c == y));
System.out.println("q == y " + (q == y));
System.out.println("a == x " + a.equals(x));
System.out.println("a == x " + a.equals(x));
System.out.println("c == y " + c.equals(y));
System.out.println("q == y " + q.equals(y));
== 这块进行比较的时候,会对Integer对象进行自动拆箱,也就是调用intValue方法,方法如上。两个基本数据类型进行==判断,根据值比较,所以结果为true。这块可能有人会问,为什么不是对int类型进行自动装箱处理呢?其实这块是java根据一个很明显的道理进行设计的:如果有人比较一个int类型的值和Integer类型的值,是想比较什么呢?肯定是值呀,所以这块是对Integer对象进行拆箱而不是对int类型装箱了。
调用equals方法的肯定是Integer对象,但是Integer类中重写的equals方法参数是一个Object类型呀,怎么能传递一个基本数据类型进去呢?所以,这块又是一个自动装箱的表现,当传递一个int类型给equals这个方法时,java会自动将这个值打包装箱为Integer类,而Integer类的最终父类又是Object,所以这块参数的问题就解决了,然后就是两个Integer对象进行equals判断,返回true。
参考: