== 和 equals() 的区别
先说总结吧。
== 比较的是两个对象的内存地址是否相等。简单的说,判断两个对象是不是同一个对象。对于基本数据类型,== 比较的是值;对于引用数据类型,== 比较的是内存地址。
equals() 方法的作用也是判断两个对象是否相等,但它一般有两种使用情况:
- 类没有覆盖 Object 类的 equals() 方法时,则通过 equals() 比较该类的两个实例对象时,实际上是比较这两个对象在内存中的地址,等价于 == 。
- 类覆盖了 Object 类的 equals() 方法时,一般需要重写该类的 equals() 方法,当两个对象的内容相同时,认定它们是相等的,返回结果为 true 。
以下代码是 Object 类中的 equals() 方法,我们可以看到,该方法实际比较的是两个对象的内存地址是否相等。
public boolean equals(Object obj) { return (this == obj); }
以下是重写 Object 类的 equals() 的代码示例。
这是一个 Student 类,有个属性值 name ,当两个实例对象的 name 值相等时,便认为两个对象是相等的。
public class Student { private String name; //当名称一样,可以认为两个对象是相等的 public Student(String name){ this.name=name; } }
测试代码:
public static void main(String[] args) { Student s1=new Student("张三"); Student s2=new Student("张三"); System.out.println(s1.equals(s2)); }
运行代码,输出结果为
false
说明:
虽说两个实例对象的 name 值都为“张三”,但未重写 Object 类的 equals() 方法,所以此时调用 equals() 方法比较的是两个对象在内存中的地址,因为这两个对象都是 new 出来的,所以它们两个是不同的对象,它们的内存地址也不相同,故结果为 false 。
现在,我们在 Student 类中重写 equals() 方法,代码如下:
public class Student { private String name; //当名称一样,可以认为两个对象是相等的 public Student(String name){ this.name=name; } /** * 重写 Object 中的 equals() 方法 * @param object * @return */ public boolean equals(Object object){ if (object instanceof Student){ Student student=(Student)object; if (this == student){ //两个对象的地址相同,则它们是相同的 return true; } if (this.name.equals(student.name)){ //两个对象的name值相同,也认为它们是相同的 return true; } } return false; } }
测试代码:
public static void main(String[] args) { Student s1=new Student("张三"); Student s2=new Student("张三"); System.out.println(s1.equals(s2)); }
运行结果为:
true
下面用 String 对 == 和 equals() 做进一步的说明。
代码示例:
public static void main(String[] args) { String a="abc"; String b="abc"; String c=new String("abc"); String d=new String("abc"); String e="ab"+"c"; if (a==b){ System.out.println("a与b的地址相同"); } if (a.equals(b)){ System.out.println("a与b的内容相同"); } if (c==d){ System.out.println("c与d的地址相同"); } if (a==c){ System.out.println("a与c的地址相同"); } if (a.equals(c)){ System.out.println("a与c的内容相同"); } if (a==e){ System.out.println("a与e的地址相同"); } if (a.equals(e)){ System.out.println("a与e的内容相同"); } }
运算结果:
a与b的地址相同
a与b的内容相同
a与c的内容相同
a与e的地址相同
a与e的内容相同
说明:
String 中的 equals() 方法是被重写过的,因为 Object 的 equals() 方法是比较的对象的内存地址,而 String 的 equals() 方法比较的是对象的值。
以下代码是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; }
当创建 String 类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个 String 对象。