在java面试题中,==和equals的区别时很常见的一道题,一般答案来说是这样的:
==:如果是基本数据类型,会比较的是变量的值,如果是引用数据类型比较的是地址值(两个对象是否指向同一块内存);
equals:没有重写比较的是两个对象的地址值,重写之后比较的是变量的值。
于是我去查看了String类中的源码:
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;
}
没有注释就很难受,第一个if中比较的是两个对象在内存中的地址(是不是在同一个内存块中);
第二个if首先判断了传进来的anObject是否是一个String类型的参数,instanceof 是 Java 的保留关键字。它的作用是测试它左边的对象(必须是引用数据类型)是否是它右边的类的实例,返回 boolean 的数据类型。
这个value其实是String类的一个属性也就是String的值,另一个为hash,看英文注释应该是缓存String的hash code,也就是指向堆内存的地址。
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
你会发现String的值居然是 一个char类型的数组,如果不太好理解请看下面这段代码:
public class StringCode {
private static final char[] value = {'k','n','i','g','h','t'};
private static final String STR = "knight";
public static void main(String[] args) {
System.out.println(value);
System.out.println(STR);
}
}
结果:
这里引用 一篇文章中的图方便大家理解(原文章地址:https://www.cnblogs.com/zhangyinhua/p/7689974.html):
public class Apple {
public static void main(String[] args) {
String a = "abc";
String b = "abc";
String c = new String("abc");
System.out.println(a==b); //true
System.out.println(a.equals(b)); //true
System.out.println(a==c); //false
System.out.println(a.equals(c)); //true
}
}
内存图: