一言蔽之 == 是引用比较,equals是值比较。
上面这句话基本能解答绝大多数关于 == 和 equals的问题,下面详细为什么会有这样的结论。

== 操作符

Java中类型可以分为基本类型和引用类型。 == 比较两个值可以分成基本类型的比较和引用类型的比较两种情况。对于基本类型的比较,只要它们的值相等,即为相等。因为基本类型的引用地址被存放在栈里面,两个值相同的基本类型指向同一个堆内存地址,取的是同一个内存地址。对于引用类型,则需要引用地址相等,才为相等。因为引用类型存放在堆当中,每一个引用类型在堆内都有自己的引用地址

image.png

equals

其实本质上 == 和 equals 是等价的。它们都在比较两个对象在内存中的引用地址,这是 equals的源码

  1. public boolean equals(Object obj) {
  2. return (this == obj);
  3. }

但通常使用 equals 和 == 的效果不一样,原因就在于 equals 方法被 String和 Integer 重写了。重写之后equals 只比较两个对象的值是否相等,而不需要引用相等

  1. public boolean equals(Object anObject) {
  2. if (this == anObject) {
  3. return true;
  4. }
  5. if (anObject instanceof String) {
  6. String anotherString = (String)anObject;
  7. int n = value.length;
  8. if (n == anotherString.value.length) {
  9. char v1[] = value;
  10. char v2[] = anotherString.value;
  11. int i = 0;
  12. while (n-- != 0) {
  13. if (v1[i] != v2[i])
  14. return false;
  15. i++;
  16. }
  17. return true;
  18. }
  19. }
  20. return false;
  21. }

例子

最后看几个例子:

  1. String x = "string";
  2. String y = "string";
  3. String z = new String("string");
  4. System.out.println(x==y); // true
  5. System.out.println(x==z); // false
  6. System.out.println(x.equals(y)); // true
  7. System.out.println(x.equals(z)); // true
  1. x和y是基本类型,且值相等。 true
  2. x和z值相等,但引用地址不一样。new String() 新建了一个引用。 false
  3. equals只比较值相等。 true
  4. 值相等。 true

参考文章

  1. 面试题|Java基础17道常见面试题:https://zhuanlan.zhihu.com/p/94095050
  2. 关于java String的“==”和equals()比较、引用的小问题:https://blog.csdn.net/barryhappy/article/details/6082823
  3. equals 和 == 的区别:https://www.jianshu.com/p/9cbed9f33a4d