java的area方法,为什么Java的Area#equals方法不会覆盖Object#equals?

I just ran into a problem caused by Java's java.awt.geom.Area#equals(Area) method. The problem can be simplified to the following unit test:

@org.junit.Test

public void testEquals() {

java.awt.geom.Area a = new java.awt.geom.Area();

java.awt.geom.Area b = new java.awt.geom.Area();

assertTrue(a.equals(b)); // -> true

java.lang.Object o = b;

assertTrue(a.equals(o)); // -> false

}

After some head scratching and debugging, I finally saw in the JDK source, that the signature of the equals method in Area looks like this:

public boolean equals(Area other)

Note that it does not @Override the normal equals method from Object, but instead just overloads the method with a more concrete type. Thus, the two calls in the example above end up calling different implementations of equals.

As this behavior has been present since Java 1.2, I assume it is not considered a bug. I am, therefore, more interested in finding out why the decision was made to not properly override the equals method, but at the same time provide an overloaded variant. (Another hint that this was an actual decision made is the absence of an overwritten hashCode() method.)

My only guess would be that the authors feared that the slow equals implementation for areas is unsuitable for comparing equality when placing Areas in Set,Map,etc. datastructures. (In the above example, you could add a to a HashSet, and although b is equal to a, calling contains(b) will fail.) Then again, why did they not just name the questionable method in a way that does not clash with such a fundamental concept as the equals method ?

解决方案

RealSkeptic linked to JDK-4391558 in a comment above. The comment in that bug explains the reasoning:

The problem with overriding equals(Object) is that you must also

override hashCode() to return a value which guarantees that equals()

is true only if the hashcodes of the two objects are also equal.

but:

The problem here is that Area.equals(Area) does not perform a very

straight-forward comparison. It painstakingly examines each and every

piece of geometry in the two Areas and tests to see if they cover the

same enclosed spaces. Two Area objects could have a completely

different description of the same enclosed space and equals(Area)

would detect that they were the same.

So basically we're left with an array of not-so-pleasant options, such as:

deprecate equals(Area) and create an alternate name for that

operation, such as "areasEqual" so as to avoid the confusion.

Unfortunately, the old method would remain and would be linkable and

would trap many people who were intending to invoke the equals(Object)

version.

or:

deprecate equals(Area) and change its implementation to be exactly

that of equals(Object) so as to avoid semantic problems if the wrong

method is called. Create a new method with a different name to avoid

confusion to implement the old functionality provided by equals(Area).

or:

implement equals(Object) to call equals(Area) and implement a dummy

hashCode() which honors the equals/hashCode contract in a degenerate

way by returning a constant. This would make the hashCode method

essentially useless and make Area objects nearly useless as keys in a

HashMap or Hashtable.

or other ways to modify the equals(Area) behavior that would either change its semantics or make it inconsistent with hashCode.

Looks like changing this method is deemed by the maintainers to be neither feasible (because neither option outlined in the bug comment quite solves the problem) nor important (since the method, as implemented, is quite slow and would probably only ever return true when comparing an instance of an Area with itself, as the commenter suggests).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值