==号和equals()方法都是比较是否相等的方法,那它们有什么区别和联系呢?
首先,==号在比较基本数据类型时比较的是值,而用==号比较两个对象时比较的是两个对象的地址值。
int x=6;
int y=6;
String s1=new String("aaa");
String s2=new String("aaa");
System.out.println(x==y);
//true
System.out.println(s1==s2);
//false
System.out.println(s1.equals(s2));
//true
String s3="bbb";
String s4="bbb";
System.out.println(s3==s4);
//true
System.out.println(s3.equals(s4));
//true
当我们想要比较两个字符串是否相同时,要特别注意,我们实际上是想比较字符串的内容是否相同。必须使用equals()
方法而不能用==
。
String s3="bbb";
String s4="bbb";
System.out.println(s3==s4);
//true
System.out.println(s3.equals(s4));
//true
String s5="BBB".toLowerCase();
System.out.println(s5);
//bbb
System.out.println(s3==s5);
//false
System.out.println(s3.equals(s5));
//true
从表面上看,s3,s4两个字符串用==
和equals()
比较都为true
,但实际上那只是Java编译器在编译期,会自动把所有相同的字符串当作一个对象放入常量池,自然s1
和s2
的引用就是相同的。
所以,这种==
比较返回true
纯属巧合。s3==s5的结果即为false。
Object中的equals()方法
public boolean equals(Object obj) {
return (this == obj);
}
那equals()方法呢?我们可以通过查看源码知道,equals()方法存在于Object类中,因为Object类是所有类的直接或间接父类,也就是说所有的类中的equals()方法都继承自Object类,而通过源码我们发现,Object类中equals()方法底层依赖的是==号,那么,在所有没有重写equals()方法的类中,调用equals()方法其实和使用==号的效果一样,也是比较的地址值,然而,Java提供的所有类中,绝大多数类都重写了equals()方法,重写后的equals()方法一般都是比较两个对象的值。
package com.learn.collection.list;
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
public class Test2 implements Serializable {
public static void main(String[] args) {
Person p1=new Person("aaa","zzz",6);
Person p2=new Person("aaa","zzz",6);
System.out.println(p1.equals(p2));
//true
//如果Person类中没有equals方法,比较结果则为false
}
}
class Person {
String firstName;
String lastName;
int age;
public Person(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
@Override
public boolean equals(Object o){
if(o instanceof Person){
Person p= (Person) o;
return Objects.equals(this.firstName,p.firstName)&&Objects.equals(this.lastName,p.lastName)&&this.age==p.age;
}
return false;
}
}
p1和p2比较的是各个字段的值是否相等,基本数据类型使用==判断,引用类型用Objects.equals()
比较。
String s1=new String("aaa");
String s2=new String("aaa");
System.out.println(s1==s2);
//false
这里其实创建了两次对象,一次是在常量池中创建了对象"aaa",一次是在堆内存中创建了对象s1,所以s1和s2的地址值不相等。
注:
1.参考自
2.java 中的toString()方法
Object中的toString()方法:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
返回该对象的字符串表示。通常, toString
方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。建议所有子类都重写此方法。
Object
类的 toString
方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@
”和此对象哈希码的无符号十六进制表示组成。
因为它是Object里面已经有了的方法,而所有类都是继承Object,所以“所有对象都有这个方法”。
它通常只是为了方便输出,比如System.out.println(xx),括号里面的“xx”如果不是String类型的话,就自动调用xx的toString()方法。
Person p1=new Person("aaa","zzz",6);
Person p2=new Person("aaa","zzz",6);
System.out.println(p1.equals(p2));
//true
System.out.println(p1);
System.out.println(p2);
System.out.println(p1==p2);
//com.learn.collection.list.Person@34ce8af7
//com.learn.collection.list.Person@b684286
//false 比较的是两个对象的地址