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

==是一个引用比较,即两个对象都指向相同的内存位置 .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)为基础对对象进行比较

但= =

还比较对象的引用。

其他回答

==和=之间的区别让我困惑了一段时间,直到我决定仔细研究一下。 他们中的许多人说比较字符串时应该使用equals而不是==。希望在这个回答中我能说出区别。

回答这个问题的最好方法就是问自己几个问题。让我们开始吧:

下面程序的输出是什么:

String mango = "mango";
String mango2 = "mango";
System.out.println(mango != mango2);
System.out.println(mango == mango2);

如果你说,

false
true

我会说你是对的,但你为什么那么说呢? 如果你说输出是,

true
false

我会说你错了,但我还是会问你,为什么你认为那是对的?

好的,让我们试着回答这个问题:

下面程序的输出是什么:

String mango = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango3);
System.out.println(mango == mango3);

如果你说,

false
true

我会说你错了,但为什么现在是错的呢? 这个程序的正确输出是

true
false

请比较以上的程序并试着思考一下。

好的。现在这可能会有帮助(请阅读:打印对象的地址-不可能,但我们仍然可以使用它)。

String mango = "mango";
String mango2 = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango2);
System.out.println(mango == mango2);
System.out.println(mango3 != mango2);
System.out.println(mango3 == mango2);
// mango2 = "mang";
System.out.println(mango+" "+ mango2);
System.out.println(mango != mango2);
System.out.println(mango == mango2);
 
System.out.println(System.identityHashCode(mango));
System.out.println(System.identityHashCode(mango2));
System.out.println(System.identityHashCode(mango3));

你能不能试着想想上面代码的最后三行输出: 对我来说,ideone打印了这个(你可以在这里检查代码):

false
true
true
false
mango mango
false
true
17225372
17225372
5433634

哦!现在你看到identityHashCode(mango)等于identityHashCode(芒果2)但它不等于identityHashCode(芒果3)

即使所有的字符串变量芒果,芒果2和芒果3都有相同的值,即“芒果”,identityHashCode()对所有变量仍然不相同。

现在尝试取消注释这一行// mango2 = "mang";并再次运行它,这一次你将看到所有三个identityHashCode()是不同的。 嗯,这是个有用的提示

我们知道如果hashcode(x)=N并且hashcode(y)=N => x等于y

我不确定java内部是如何工作的,但我假设这就是我说的:

mango = "mango";

Java创建了一个字符串“mango”,由变量mango指向(引用),就像这样

mango ----> "mango"

下一行我说

mango2 = "mango";

它实际上重用了相同的字符串“mango”,看起来像这样

mango ----> "mango" <---- mango2

mango和mango2都指向同一个引用 当我说

mango3 = new String("mango")

它实际上为mango创建了一个全新的引用(字符串)。就像这样,

mango -----> "mango" <------ mango2

mango3 ------> "mango"

这就是为什么当我输出mango == mango2的值时,输出的是true。当我输出mango3 == mango2的值时,它输出false(即使值是相同的)。

当你取消注释// mango2 = "mang"; 它实际上创建了一个字符串“mang”,将我们的图形变成这样:

mango ---->"mango"
mango2 ----> "mang"
mango3 -----> "mango"

这就是为什么identityHashCode对所有人来说都不一样。

希望这对你们有帮助。 实际上,我想生成一个测试用例,其中==失败而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)

欢呼:-)

如果不重写.equals(), ==和.equals()都指向同一个对象。

一旦你重写了.equals(),你想要做的就是你的愿望。你可以比较调用对象的状态和传入对象的状态或者你可以调用super。equals()

可能值得添加的是,对于基本类型的包装器对象,例如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.");

它是恒等和等价的区别。

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

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

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