java 中的平等
Equality in java
java 中的 ==
运算符检查两个对象是否位于同一内存位置。这是否意味着如果 object1 != object2
则 object1
未与 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 是假的。
首先 - object1
和 object2
本身不是对象,它们每个都是持有对象引用的变量(除非为 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;
}
}
java 中的 ==
运算符检查两个对象是否位于同一内存位置。这是否意味着如果 object1 != object2
则 object1
未与 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 是假的。
首先 - object1
和 object2
本身不是对象,它们每个都是持有对象引用的变量(除非为 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; } }