java 中的平等

Equality in java

java 中的 == 运算符检查两个对象是否位于同一内存位置。这是否意味着如果 object1 != object2object1 未与 obejct2 链接?通过链接,我的意思是如果 object1 被更改,那么 obejct2 也会被更改。

它检查两个指针​​是否相等,即。他们指向同一个对象。

== 检查两个 引用 是否相同。

换句话说:如果检查return为真,则只有一个对象。

如果 return 为假,则有 两个 个对象。

但是,当然,可以很容易地编写一些代码,其中 a != b;但是 a.foo() 会对 b.

产生影响

喜欢:

class Bar {
  private static int counter = 0;
  void foo() { counter++ };
  int getCounter() { return counter; }

当你现在拥有:

Bar a = new Bar();
Bar b = new Bar();

那么a != b;但是,当你这样做时

System.out.println(b.getCounter());
a.foo();
System.out.println(b.getCounter());  

将打印 0,然后打印 1。

因此,从本质上讲,您第二个问题的答案是:a != b 暗示 "doing something with a" 对 b 没有任何作用"。

但郑重声明 - 最后一句话是为什么 static 可以被视为良好 OO 设计中的异常的原因;正是为了这样的 "strange" 副作用。

编辑以在 "what happens with containers and clone"?

上回答

当然,当你有类似的东西时:

List<WhatEver> a = some list containing one object "X"
List<WhatEver> b = a "clone" of a

那么a != b;但是当然;当您调用影响 b.get(0) 的 a.get(0).foo() 时...因为两个列表在内部都指向相同的 X

你看:在那种情况下,a.equals(b) 会 return true;而 a == b 是假的。

首先 - object1object2 本身不是对象,它们每个都是持有对象引用的变量(除非为 null)。因此,== 不检查两个对象是否在同一内存位置(因为这不可能发生),而是检查两个变量是否持有对同一对象的引用。因此,如果 object1 != object2,这两个变量不包含对同一对象的引用。

我认为用一个例子会更容易理解,恕我直言,最好的例子是当你覆盖 equals 时,当你创建具有姓名和年龄的 Human 实例时,方法 equals 如下:

  • 如果(例如 John)与 John 相同,则两个人都是平等的(John 的克隆)
  • 如果传递的对象不是人,那么 return 错误,它们不相同(例如狗,谁知道)
  • 然后逐个字段检查是否是同一个人,虽然他们是不同的人,但可能还有另一个相同年龄的约翰。

         public class Human {
    
            private final String name;
            private final int age;
    
            public Human(String name, int age) {
                this.name = name;
                this.age = age;
            }
    
            public String getName() {
                return this.name;
            }
    
            public int getAge() {
                return this.age;
            }
    
            @Override
            public boolean equals(Object o) {
                if (this == o) {
                    return true;
                }
    
                if (!(o instanceof Human)) {
                    return false;
                }
    
                Human that = (Human) o;
    
                if (this.age != that.age) return false;
                return this.name != null ? this.name.equals(that.name) : that.name == null;
    
            }
    
            @Override
            public int hashCode() {
                int result = name != null ? name.hashCode() : 0;
                result = 31 * result + age;
                return result;
            }
        }