==和equals的区别是什么?
==和 equals 的区别是什么呢?对于这个问题本身不难,但是在面试的时候却被问到的频率很高,然而大部分人的回答都不够全面,是的面试官听着不满意,所以今天我们就来好好全面总结下这个问题。
1.典型回答
对于 Object 来说,其equals
方法底层实现就是==
,如下 JDK 的 Object 源码如下:
public boolean equals(Object obj) { return (this == obj); }
也就是说,对于 Object 对象来说,equals 和 == 都是一样的,都是比较对象的引用是否相同。但是,在 JDK 中的其他类中通常会重写 equals 以实现具体的值比较,例如 Integer 中的 equals 和 String 中的 equals 等,如下源码所示。
Integer 中的 equals 实现源码如下:
public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; }
从上述源码可以看出,Integer 中会先将 Integer 对象转换成基础类型 int 值来进行比较,所以此时就不再是对比两个对象的引用了,而是对比两个对象的值是否相等。
String 中的 equals 实现源码如下:
public boolean equals(Object anObject) { if (this == anObject) { // 引用相同返回 true,引用相同,那么值肯定相同了 return true; } return (anObject instanceof String aString) && (!COMPACT_STRINGS || this.coder == aString.coder) && StringLatin1.equals(value, aString.value); // equals 为下面的 equals 方法 } @IntrinsicCandidate public static boolean equals(byte[] value, byte[] other) { if (value.length == other.length) { for (int i = 0; i < value.length; i++) { // 循环每个字符对比,本质是值比较 if (value[i] != other[i]) { return false; } } return true; } return false; }
从 String 中的 equals 中可以看出,它和 Integer 一样,是将 Object 中的引用比较重写成了值比较了。
2.考点分析
所以,对于 Object 来说,== 和 equals 都是一样的,都是用来对比两个对象的引用是否相同的,而其他 Java 中的类中,如 String 或 Integer 等,通常都会重写 equals 让其变为比较具体的值是否相同,而非引用是否相同。 所以,我们通常会使用 == 来对比两个对象的引用是否相同,而使用 equals 对比两个值是否相同(前提条件是重写了 equals 方法)。
3.知识扩展
如果我们自定义一个类,并且想和 Integer 或 String 中的 equals 一样,用其对比值而非引用是否相同的实现代码如下:
public class Person { private String name; private int age; // 忽略构造方法和 Getter、Setter 方法...... @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null || getClass() != obj.getClass()) { return false; } Person other = (Person) obj; return this.age == other.age && this.name.equals(other.name); } }
总结
对于 Object 来说,equals 是用 == 实现的,所以二者是相同的,都是用来比较两个对象的引用是否相同的,但 Java 中的其他类,都会重写 equals 让其变为值比较,而非引用比较,如 Integer 和 String 都是这样。