在比较equals和==之前我们先了解一下equals:
了解equals()
equals方法是基类Object中的方法,因此对于所有的继承于Object的类都会有该方法。我们观察源码:
很显然,在Object类中,equals方法是用来比较两个对象的引用是否相等,即是否指向同一个对象。但是我们发现以下代码输出结果为true。
String a = new String("aaa");
String b = new String("aaa");
System.out.println(a.equals(b));
我们知道这里明明创建了两个对象,分别为a、b。按理说两个对象应该各自独立应该返回false。而现在返回值为true。我们看到这里是调用了对象a下的equals方法。我们看看这个equals方法
发现了这个equals方法被重写了,用来比较指向的字符串对象所存储的字符串是否相等。要知道这个方法实际上是String类下的方法。所以我们现在总结如下:
equals方法是基类Object中的方法,但是在String类中,该方法被重写了。这两者的区别是在Object类中的方法是比较两个对象的引用是否相等,即是否指向同一个对象。而到了String类中。它比较的是字符串对象所存储的字符串是否相等,及字符串内容是否相等。
同理对于基本类型的包装类型,比如Boolean、Character、Byte、Shot、Integer、Long、Float、Double等的引用变量中,都对equals方法进行了重写。重写后的的比较也都是对对那些存储的内容进行比较。
比较==和equals
先看代码:
String a="aaa"; //存储在常量池中
String b="aaa"; //存放到常量池中
String c = new String("aaa"); //对象存储在堆中
String d = new String("aaa"); //在堆中又创建了个String对象
System.out.println(a==b); //==比较的是地址 ------true
System.out.println(a.equals(b));//equals比较的是内容 ------true
System.out.println(a==c); //-------false
System.out.println(a.equals(c)); //-------true
System.out.println(c==d); //==比较的是地址 -----false
System.out.println(c.equals(d)); //equals比较的是内容 ------true
我们依次分析:
首先我们分析c和d的比较:
- c==d:的比较结果为false,我们知道c和d分别创建了两个String对象,而这两个对象在堆中是独立存在的(如果不懂,可以留言),所以这两个对象的地址是不同的,所以返回的类型为false
- c.equals(d):比较结果为true,我们知道因为在String类中重写了euqals方法,所以此时比较的对象中的内容。
a和c的比较:
- a==c:因为a和b都是字符串常量,所以a和b的值都存储在常量池中。我们知道在常量池中字符串内容相等的常量,通常只会存储一份。也就是说这里声明了字符串变量a和b,其指向的是同有个数据。而c是一个String对象,其数据是存储在堆中。二者的地址完全不同。所以不同结果为false。
- a.equals(c):我们知道String类中重写了equals方法,所以这里是常量池中数据与堆中的数据相比较。结果为true。
a和b比较:
- a==b:,所以在常量池中的存储只有一份,两个变量指向的是一个地址。所以结果为ture。
- a.equals(b):同上,equals被String类重写,所以比较的是两者的数据内容。结果为true。
总结:
- 在String类型以及基本类型的包装类型,比如Boolean、Character、Byte、Shot、Integer、Long、Float、Double等的引用变量中,equals方法均在这些类均被重写,重写后的equals方法比较的是两者之间的内容。而Object类中比较的是两个对象的引用是否相等,即是否指向同一个对象。
- ==在比较变量之间是比较的内容,而比较对象时,则是对地址的比较。
欢迎留言讨论!!