![](/img/trans.png)
[英]Can .equals be overridden such that a.equals(a) returns false?
[英]When does a.equals(a) return false?
我想知道哪些是java中的变量不能相等(使用equals()
方法)自身的情况。 我不是在这里讨论对象而是变量本身(只要代码编译并在调用equals时返回false)。 到目前为止我发现的唯一情况是:
public class A {
public static void main(String args[]){
A a = new A();
System.out.println(a.equals((a = null)));
}
}
还有其他情况, a.equals(a)
会返回false吗?
编辑:不允许覆盖equals()
,但只要变量a
在最后进行比较,就可以根据需要修改(强制转换,继承) a
。
它可能在多线程上下文中返回false,即使使用equals
实现equals
合同的equals
实现:
class Test {
public static final A a = new A();
public static void main(String... args) throws Exception {
new Thread() {
@Override
public void run() {
while (true) {
a.x += 1;
}
}
}.start();
Thread.sleep(10);
System.out.println(a.equals(a)); // <---
}
}
class A {
int x;
@Override
public boolean equals(Object o) {
return (o instanceof A) && ((A)o).x == x;
}
}
false
从Oracle的Object文档:
public boolean equals(Object obj)
指示某个其他对象是否“等于”此对象。
equals方法在非null对象引用上实现等价关系:
It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
For any non-null reference value x, x.equals(null) should return false.
类Object的equals方法实现了对象上最具辨别力的等价关系; 也就是说,对于任何非空引用值x和y,当且仅当x和y引用同一对象时,此方法才返回true(x == y的值为true)。
请注意,通常需要在重写此方法时覆盖hashCode方法,以便维护hashCode方法的常规协定,该方法声明相等的对象必须具有相等的哈希代码。
参数:obj - 要与之比较的引用对象。 返回:如果此对象与obj参数相同,则返回true;否则返回false。 否则是假的。
所以回到你的问题并分析文档
当a.equals(null);
时,它是错误的a.equals(null);
当比较a
和b
(分别为A
类和B
类A
物体)时,即a.equals(b)
也将返回false。
在其他情况下,这是真的,因为:
It is reflexive: for any non-null reference value x, x.equals(x) should return true.
它清楚地说:没有空引用X(或a
在这种情况下):
a.equals(a);
将是真的
我支持khale和Frakcool的回复。 除此之外,如果你只是需要另一个案例来获取虚假尝试
System.out.println(a.equals((a = new A())));
赋值实质上返回分配的内容,如果它不是调用对象本身,则等于false。
我不认为我们有办法完成这项任务,因为呼唤等于自己总是如此。 让我解释一下你想要实现的目标。
String foo = "";
bool a = foo.equals(foo); // Here true, the easy one
foo = "some value";
bool b = foo.equals(foo); // Here true, since it's changed and then compared to itself again
bool c = foo.equals(foo="some other value"); // Here should be true again, since the compiler takes first the arguments, makes the assignation, and then makes the equals method execution, so in compiler what happens is:
// 1. Make foo = "some other value"
// 2. Compares foo with foo
// Foo is already changed, so is equals to itself
我没有尝试过自己,但那应该是什么。 如果由于某种原因编译器中断bool c = ...
这是因为equals不接收String实例化作为String参数。
使用正确实现的.equals()
, a.equals(a)
永远不会为false。
将表达式传递给equals方法:
a.equals(a = null);
并不比以下更特别:
a.equals(b); or a.equals(null);
你只是比较两个不同的值,将表达式填充到equals调用不会改变它。
一个非常有趣的案例是你有一个盒装Float
,考虑这个代码:
Float alpha = +0.0f;
Float beta = -0.0f;
boolean equal = alpha.equals(beta);
System.out.println("Equal: " + equal);
boolean equality = alpha.floatValue() == beta.floatValue();
System.out.println("Equality: " + equality);
这将打印true
的第一个和false
第二。
Float.NaN
的情况恰恰相反。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.