代码演示:
public class Test { public static void main(String[] args){ // 案例一 String str1 = new String("hello"); String str2 = "hello"; System.out.println(str1 == str2); // false System.out.println(str1.equals(str2)); // true // 案例二 String str3 = "world"; String str4 = "world"; System.out.println(str3 == str4); // true System.out.println(str3.equals(str4)); // true } }
问题说明:
- “ == ” 它的应用场景大致分为两大类,第一类是用来比较基本数据类型的(Java中八大基本数据类型:byte,short,int,float,long,double,char,boolean),在基础数据类型之间他们是直接比较值的。第二类是用来比较对象的,它会直接比较两个对象的内存地址,也就是说,除非两个对象指向同一个地址,否则始终是false.
- equals()方法是Object基类中的方法,所以任何类都会继承这个方法,只是有些类重写了这个方法,就比如String类,我们可以结合String类equals()源码来解释。
// String类中重写的equals()方法 源码: public boolean equals(Object anObject) { if (this == anObject) { // 首先判断是否为同一个对象,若是直接返回true return true; } if (anObject instanceof String) { // 接着判断传进来的是否是String的实例,若是则继续判断 String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { // 首先判断两个字符串的长度,若不是等长直接返回false char v1[] = value; // 字符串的底层是用一个名为value的字符数组来装载数据的。 char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) // 比较每个字符是否相等 return false; i++; } return true; } } return false; }
总结:
- 案例一中,str1和str2是不同的对象,但是内容相同,因为“==”是比较对象的内存地址的,所以返回false。而重写的equals()方法是比较内容的值的,所以返回true.
- 案例二中,为什么str3和str4用“==”比较会返回true呢?不应该返回false吗?其实是Java会维护一个公共的存储池,若是直接用纯字符串来建一个String对象,那么它会先检查存储池中有没有这个字符串,若没有就创建一个,若有就将这个变量指向存储池中已经存在的对象。所以str3和str4是指向同一个对象的,故返回true。