是否可以覆盖.equals,以便a.equals(a)返回false?

时间:2015-08-24 05:45:14

标签: java equals

我对这一切仍然很新鲜,但我正在努力获得我的OCAJP认证(Java)。我记得以前读过我在讨论这个问题时可以覆盖.equals方法:

Question from Enthuware prep materials:

就我而言,现在这些问题一直很恶劣。扭曲你认为你知道的每件小事,迫使你学习所有的细枝末节。现在我已经猜到了E,但我并不认为D是正确的。当然,我的意思是99.9%,但我认为这是一个基于措辞的技巧问题。

这让我思考,这是真的吗?我的意思是,如果我在考试中得到问题,我现在知道如何回答这个问题,但是在压倒一切的疯狂深深的深渊中,是否有可能创造一种a.equals(a)返回false的情况?我觉得这会让亚里士多德生气...

4 个答案:

答案 0 :(得分:47)

请注意abc是原始包装类的实例(例如Integer,Double等)。这些类是最终的,无法扩展,因此您无法覆盖其equals实现。

因此a.equals(a)将始终返回true,因为这些类正确实现了equals

答案 1 :(得分:21)

由于equals(...)不是Object的最终方法,是的,在不同的情况下很可能

@Override
public boolean equals(Object obj) {
    return false;
}

然而,这个问题具体说明这些是原始包装(例如IntegerBoolean等),因为这些类是最终的,所以你不能扩展它们,因此a.equals(a)将始终返回true

答案 2 :(得分:7)

整数a.equals(a)可以返回false

但你必须非常邪恶并使用反射和多线程:

如果您运行此代码,竞争条件可能会在比较发生时更改myInt的内部值。如果你想模拟这个条件,只需在Integer.intValue()内设置一个断点,在debug中运行代码并点击continue。这将产生延迟,人为地创建竞争条件,控制台将返回false。

class IntegerEqualsTest
{
    public static void main( final String[] args )
    {
        final Integer myInt = new Integer( 420 );

        new Thread() {
            public void run() {
                try {
                    final Field f = Integer.class.getDeclaredField( "value" );
                    f.setAccessible( true );
                    f.setInt( myInt, 100 );
                } catch( final Exception e ) {}
            }; }.start();

        System.out.println( myInt.equals( myInt ) );
    }
}

答案 3 :(得分:6)

其他答案已经回答了你的问题 - 不,这对于Java的原始包装类是不可能的。

我将尝试解决“问题背后的问题”:这可能与其他类有关吗?

  [...]在压倒一切的疯狂深深的深渊中,是否有可能   创建a.equals(a)返回false的情况?我觉得这样   会让亚里士多德生气...

这实际上是一个很好的问题,答案是:是的,有可能创造这种情况,是的,这会让亚里士多德生气。实际上,我不知道是否会让亚里士多德生气,没有认识他,但对于那些必须使用该代码的人来说肯定会引起很多的悲痛。

事情是:与Object.equals()相关联的合同

  

equals方法在非null上实现等价关系   对象引用:

     

[...]

     

它是自反的:对于任何非空引用值x,x.equals(x)应该返回true。

Javadocs for Object.equals

是的,在创建自己的课程时,您可以违反此合同。 (遗憾的是)编译器或运行时没有任何东西阻止你。

但是,很多代码都依赖于这个合同,所以如果你违反它,任何使用equals的代码都可能以神秘的方式失败。

一个例子:Java自己的Collection类(java.util.Collection和朋友)依赖于equals。如果将未正确实现equals的类的实例放入集合中,则会发生奇怪的事情,例如有时包含实例的集合,有时不包含。