Java 中的“==”和“equals”,以及Integer数据缓存

来源:互联网 发布:it香港 编辑:程序博客网 时间:2024/06/13 07:07

       我们在写程序过程中,一般都遇到一种情况,那就是我们都会去比较一些数据、一些字符串或者一些对象是否是相等,这个时候我们自然就用到了“==”或者“equals”,这两种比较方法。但是在什么情况下我们会用到"==",而在什么情况下又要用“equals”呢?这是个问题?

      对于“==”这个是比较的两个变量是否相等,比较的是两个变量在内存中的值是否一致,要比较两个基本数据类型或者是引用变量类型,只能用“==”来比较。而对于引用类型来说,情况就不一样了,对于引用类型,“==”比较的是两个引用类型的内存地址是否一致,意思就是这两个引用指代的是不是同一块内存的首地址,若是则返回true,否则是false。

对于“equals”来说,比较的就是两个对象的内容是否一致,当然比如 

String a=new String("foo");

String b=new String("foo");

对象a,b是两个不同的对象,在内存中的地址是不一致的,如果用“==”,返回的是false,但是用equals返回的是true,因为他们是的地址不一样但是内容是一致的。

我们看下equals的实现代码:

boolean equals(Object o){
return this==o;
}

意思就是说,如果比较对象的类没有重写equals的方法时,则效果和==是一样的,都是比较的对象的首地址是否一致。

下面我们来看下这个例子。

public static void main(String[] args) {          Integer i1 = 127;          Integer i2 = 127;          int i3 = 127;          int i4 = 127;         Integer i5=new Integer(127);        Integer i6=new Integer(127);        Integer i7=200;        Integer i8=200;                System.err.println("1::"+(i1 == i2));//(1)          System.err.println("2::"+(i1 == i3));//(2)          System.err.println("3::"+(i2 == i3));//(3)          System.err.println("4::"+(i3 == i4));//(4)        System.err.println("5::"+(i1 == i5));//(5)        System.err.println("6::"+(i2 == i5));//(6)        System.err.println("7::"+(i3 == i5));//(7)        System.err.println("8::"+(i6 == i5));//(8)        System.err.println("9::"+(i6 .equals(i5)));//(9)        System.err.println("10::"+(i7 == i8));//(10)        System.err.println("11::"+(i7 .equals(i8)));//(11)            }  


大家先不要看答案,自己说下,这分别输出什么??


答案是:  
1::true
2::true
3::true
4::true
5::false
6::false
7::true
8::false
9::true
10::false
11::true

大家仔细看下会发现  

 System.err.println("2::"+(i1 == i3));//(2)  true
System.err.println("7::"+(i3 == i5));//(7)true
 System.err.println("5::"+(i1 == i5));//(5)  这个却是false   求解释啊!

这个是为什么呢?
原因就是大家看Integer的源代码,就会知道,Integer使用了缓存数据,直接赋值的时候,Integer使得-128--127之间的数据都是从缓冲数据中进行取,所以所有的地址都是一致的,但是对于new出来的对象,地址都是不一致的。