我们在写程序过程中,一般都遇到一种情况,那就是我们都会去比较一些数据、一些字符串或者一些对象是否是相等,这个时候我们自然就用到了“==”或者“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出来的对象,地址都是不一致的。