1、”==”:
是算数运算符,比较的是两个引用指向的是否是同一个内存地址,也就是指向的是否是同一对象。
2、equals方法:
是属于Object的方法,是开发者自己根据具体的业务逻辑来定义该方法,用于检查两个对象的相等性,注意是让开发者自己去重写的方法。比如String类重写了equals方法。
- Object类中的equals方法:
public boolean equals(Object obj) {
return (this == obj);
}
- String类重写的equals方法
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
3、常见的==比较
- 基本数据类型
Java中的8个基本数据类型定义后时存在常量池中,而对应的封装类定义后是对象。
Integer a = new Integer(128);
Integer b1 = 128;
Integer b2 = 128;
int c1 = 128;
int d2 = 128;
//false,因为a、b都是对象,且不是同一对象
System.out.println(a == b1);
//true 此时a与c比较时会自动拆箱成为基本数据类型,故此时比较为true
System.out.println(a == c1);
//true原理同上
System.out.println(b1 == c1);
//true基本数据类型定义后,存在常量池,故为true
System.out.println(c1 == c2);
//反常点来了
//false,因为b1、b2是两个对象且不是同一对象,故为false
System.out.println(b1 == b2);
//但是b1、b2定义改为以下时:
Integer b1 = 127;//128改为127
Integer b2 = 127;
//此时照理说应该为false,但却是为true。
System.out.println(b1 == b2);
其实java在编译Integer b1 = 127的时候,被翻译成-> Integer b1 = Integer.valueOf(127);所以关键就是看valueOf()函数了。只要看看valueOf()函数的源码就会明白了。JDK源码的valueOf函数式这样的:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
看一下源码大家都会明白,对于-128到127之间的数,会进行缓存,Integer b1 = 127时,会将127进行缓存,下次再写Integer b2 = 127时,就会直接从缓存中取,就不会new了。这是需要注意的一点。
- 字符串类型
需要特别注意的是在String中,如果以这样的方法定义String a = “hello”;则定义后的字符串也是存在常量池中。
//定义后为对象
String a = new String("hello");
//定义后为字符串常量
String b = "hello";
//定义后为对象
String c = "he"+ new String("llo");
//定义后为字符串常量
String b2 = "hello";
//false是两个不同对象
System.out.println(a == b);
//false,同上
System.out.println(a == c);
//false,同上
System.out.println(b == c);
//true,因为两者都是字符串常量
System.out.println(b == b2);