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

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


当前回答

它是恒等和等价的区别。

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

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

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

其他回答

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

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

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)为基础对对象进行比较

但= =

还比较对象的引用。

例1 -

==和.equals方法只用于引用比较。它表示两个对象是否引用同一个对象。

对象类等于方法实现

public class HelloWorld{
     public static void main(String []args){
       Object ob1 = new Object();
       Object ob2 = ob1;
       System.out.println(ob1 == ob2); // true
       System.out.println(ob1.equals(ob2)); // true
     }    
}

例2 -

但是如果我们想要使用equals方法比较对象的内容,那么class必须重写对象的类equals()方法并提供内容比较的实现。这里,String类重写了用于内容比较的equals方法。所有包装器类都覆盖了用于内容比较的equals方法。

字符串类等于方法实现

public class HelloWorld{
     public static void main(String []args){
       String ob1 = new String("Hi");
       String ob2 = new String("Hi");
       System.out.println(ob1 == ob2); // false (Both references are referring two different objects)
       System.out.println(ob1.equals(ob2)); // true
     }
}

例3 -

对于String,还有一个用例。在这里,当我们将任何字符串赋值给string引用时,字符串常量就会在string常量池中创建。如果将相同的字符串赋值给新的字符串引用,则不会创建新的字符串常量,而是引用现有的字符串常量。

public class HelloWorld{
     public static void main(String []args){
       String ob1 = "Hi";
       String ob2 = "Hi";
       System.out.println(ob1 == ob2); // true
       System.out.println(ob1.equals(ob2)); // true
     }
}

注意,每当重写hashCode方法时,通常都需要重写该方法,以便维护hashCode方法的一般契约,该契约规定相等的对象必须具有相等的散列码。

Java API equals()方法契约

==运算符测试两个变量是否有相同的引用 (又名指向内存地址的指针)。

String foo = new String("abc");
String bar = new String("abc");

if(foo==bar)
// False (The objects are not the same)

bar = foo;

if(foo==bar)
// True (Now the objects are the same)

而equals()方法测试两个变量是否引用对象 具有相同的状态(值)。

String foo = new String("abc");
String bar = new String("abc");

if(foo.equals(bar))
// True (The objects are identical but not same)

欢呼:-)