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

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


当前回答

==操作符总是比较引用。但是如果

equals()方法

这取决于我们的实现,如果我们是overridden equals method,而不是在overridden method中给出的实现的基础上比较对象。

 class A
 {
   int id;
   String str;

     public A(int id,String str)
     {
       this.id=id;
       this.str=str;
     }

    public static void main(String arg[])
    {
      A obj=new A(101,"sam");
      A obj1=new A(101,"sam");

      obj.equals(obj1)//fasle
      obj==obj1 // fasle
    }
 }

在上面的代码中,obj和obj1对象包含相同的数据,但引用不相同,所以=也返回false和==。 但如果我们重写equals method than

 class A
 {
   int id;
   String str;

     public A(int id,String str)
     {
       this.id=id;
       this.str=str;
     }
    public boolean equals(Object obj)
    {
       A a1=(A)obj;
      return this.id==a1.id;
    }

    public static void main(String arg[])
    {
      A obj=new A(101,"sam");
      A obj1=new A(101,"sam");

      obj.equals(obj1)//true
      obj==obj1 // fasle
    }
 }

知道签出它将返回true和false对于相同的情况,只是我们覆盖了

等于方法。

它以对象的内容(id)为基础对对象进行比较

但= =

还比较对象的引用。

其他回答

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);

可能值得添加的是,对于基本类型的包装器对象,例如Int, Long, Double - ==如果两个值相等将返回true。

Long a = 10L;
Long b = 10L;

if (a == b) {
    System.out.println("Wrapped primitives behave like values");
}

相比之下,将上述两个long放入两个单独的数组列表中,equals将它们视为相同,而==则不同。

ArrayList<Long> c = new ArrayList<>();
ArrayList<Long> d = new ArrayList<>();

c.add(a);
d.add(b);
if (c == d) System.out.println("No way!");
if (c.equals(d)) System.out.println("Yes, this is 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类的方法版本所做的事情与比较操作相同:

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

enum FooEnum {A, B, C}

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

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

你就不会有任何问题了。

Equals()方法主要比较对象的原始内容。

如果我们写作

    String s1 = "Samim";
    String s2 = "Samim";
    String s3 = new String("Samim");
    String s4 = new String("Samim");

    System.out.println(s1.equals(s2));
    System.out.println(s2.equals(s3));
    System.out.println(s3.equals(s4));

输出将是

true 
true 
true

因为equals()方法比较对象的内容。 在first System.out.println()中,s1和s2的内容是相同的,这就是为什么它打印为真。 另外两个System.out.println()为真。

再一次,

    String s1 = "Samim";
    String s2 = "Samim";
    String s3 = new String("Samim");
    String s4 = new String("Samim");
    
    System.out.println(s1 == s2);
    System.out.println(s2 == s3);
    System.out.println(s3 == s4);

输出将是

true
false 
false

因为==运算符主要比较对象的引用,而不是对象的值。 在first System.out.println()中,s1和s2的引用是相同的,这就是为什么它返回true。

在第二个System.out.println()中,创建了s3对象,这就是为什么会创建另一个s3的引用,并且s2和s3的引用会有所不同,因此它返回“false”。

Third System.out.println(),遵循second System.out.println()的规则,这就是为什么它会返回"false"。