我想澄清一下我的理解是否正确:

==是一个引用比较,即两个对象都指向相同的内存位置 .equals()计算为对象中值的比较


当前回答

它是恒等和等价的区别。

A == b意味着A和b是相同的,也就是说,它们是内存中相同对象的符号。

A.equals (b)意味着它们是等价的,它们是在某种意义上具有相同值的对象的符号——尽管这些对象可能在内存中占据不同的位置。

注意,对于等价性,如何评估和比较对象的问题开始发挥作用——复杂的对象可能被认为是等效的,即使它们的一些内容不同。有了身份,就没有这样的问题了。

其他回答

只需记住.equals(…)必须由您试图比较的类实现。否则,就没有什么意义了;Object类的方法版本所做的事情与比较操作相同:

唯一需要对对象使用比较运算符的时候是比较枚举的时候。这是因为一次只有一个Enum值的实例。例如,给定枚举

enum FooEnum {A, B, C}

你永远不会同时拥有一个以上的A实例,对于B和c也是如此。这意味着你实际上可以像这样编写一个方法:

public boolean compareFoos(FooEnum x, FooEnum y)
{
    return (x == y);
}

你就不会有任何问题了。

String池(又名实习池)和Integer池进一步模糊了区别,并允许您在某些情况下对对象使用==而不是.equals

这可以为您提供更好的性能(?),但代价是更大的复杂性。

例如:

assert "ab" == "a" + "b";

Integer i = 1;
Integer j = i;
assert i == j;

复杂性权衡:以下内容可能会让你大吃一惊:

assert new String("a") != new String("a");

Integer i = 128;
Integer j = 128;
assert i != j;

我建议你远离这样的微观优化,总是用.equals表示对象,用==表示原语:

assert (new String("a")).equals(new String("a"));

Integer i = 128;
Integer j = 128;
assert i.equals(j);

在计算代码时,很明显(==)是根据内存地址进行比较,而equals(Object o)是比较实例的hashCode()。 这就是为什么如果以后不遇到意外,就不要破坏equals()和hashCode()之间的契约。

    String s1 = new String("Ali");
    String s2 = new String("Veli");
    String s3 = new String("Ali");

    System.out.println(s1.hashCode());
    System.out.println(s2.hashCode());
    System.out.println(s3.hashCode());


    System.out.println("(s1==s2):" + (s1 == s2));
    System.out.println("(s1==s3):" + (s1 == s3));


    System.out.println("s1.equals(s2):" + (s1.equals(s2)));
    System.out.println("s1.equal(s3):" + (s1.equals(s3)));


    /*Output 
    96670     
    3615852
    96670
    (s1==s2):false
    (s1==s3):false
    s1.equals(s2):false
    s1.equal(s3):true
    */
public class StringPool {

public static void main(String[] args) {

    String s1 = "Cat";// will create reference in string pool of heap memory
    String s2 = "Cat";
    String s3 = new String("Cat");//will create a object in heap memory

    // Using == will give us true because same reference in string pool

    if (s1 == s2) {
        System.out.println("true");
    } else {
        System.out.println("false");
    }

    // Using == with reference and Object will give us False

    if (s1 == s3) {
        System.out.println("true");
    } else {
        System.out.println("false");
    }

    // Using .equals method which refers to value

    if (s1.equals(s3)) {
        System.out.println("true");
    } else {
        System.out.println("False");
    }

    }
  }

——输出 真正的 假 真正的

基本上,==比较两个对象在堆上是否有相同的引用,因此,除非两个引用链接到同一个对象,否则这种比较将为假。

equals()是继承自Object类的方法。默认情况下,如果两个对象具有相同的引用,则此方法进行比较。它的意思是:

object1.equals(object2) <=> object1 == object2

但是,如果您希望在同一类的两个对象之间建立相等性,则应该重写此方法。如果已经重写了equals(),重写hashCode()方法也是非常重要的。

当建立平等是Java对象契约的一部分时,实现hashCode()。如果你正在使用集合,并且你还没有实现hashCode(),可能会发生奇怪的糟糕事情:

HashMap<Cat, String> cats = new HashMap<>();
Cat cat = new Cat("molly");
cats.put(cat, "This is a cool cat");
System.out.println(cats.get(new Cat("molly"));

如果您没有实现hashCode(),则在执行前面的代码后将打印null。