一、 equals 和 == 的区别是什么
== : 它的作用是判断两个对象的地址是不是相等, 即判断两个对象是不是同一个对象
基本数据类型 == 比较的是值
引用数据类型 == 比较的是内存地址
equals() : 它的作用也是判断两个对象是否相等, 但它一般有两种使用情况:
情况1:类没有覆盖equals() 方法。则通过 equals() 比较该类的两个对象时, 等价于通过“==”比较这两个对象。
情况2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法,则比较两个对象的内容是否相等;若它们的内容相等,则返回 true (即认为这两个对象相等)。
怎么理解上面的两种情况呢? 类有没有覆盖equals() 方法,评判的标准是:查看该类的源码,比如涉及到字符串比较的String.java类, 是否有覆盖equals() 方法?
android工程中的源码路径 :libcore/ojluni/src/main/java/java/lang/String.java
它有覆盖equals()方法
/**
* Compares this string to the specified object. The result is {@code
* true} if and only if the argument is not {@code null} and is a {@code
* String} object that represents the same sequence of characters as this
* object.
*
* @param anObject
* The object to compare this {@code String} against
*
* @return {@code true} if the given object represents a {@code String}
* equivalent to this string, {@code false} otherwise
*
* @see #compareTo(String)
* @see #equalsIgnoreCase(String)
*/
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = length();
if (n == anotherString.length()) {
int i = 0;
while (n-- != 0) {
if (charAt(i) != anotherString.charAt(i))
return false;
i++;
}
return true;
}
}
return false;
}
我们通过一个例子来说明:
public class Test1 {
public static void main(String[] args) {
String a = new String("ab"); // a 为一个引用
String b = new String("ab"); // b为另一个引用,对象的内容一样
String aa = "ab"; // 放在常量池中
String bb = "ab"; // 从常量池中查找
//虚拟机会在常量池中查找有没有已经存在的值和要 创建的值相同的对象,如果有就把它赋给当前引用
if (aa == bb) // true
System.out.println("aa==bb");
if (a == b) // false,非同一对象
System.out.println("a==b");
//a 和 b 都是String对象, 我们查看源码知道已经复写了 equals 方法,当执行 a.equals(b) 这句话的时候
// 就属于第二种情况,直接判断两个对象的内容是否相当, 内容都是ab 所以为true
if (a.equals(b)) // true
System.out.println("aEQb");
}
打印结果:
aa==bb
aEQb
二、总结
1. String中的equals方法是被重写过的,所以String的equals方法比较的是对象的值。
2. 当创建String类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要 创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建 一个String对象。