簡體   English   中英

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

[英]Can .equals be overridden such that a.equals(a) returns false?

我對這一切仍然很新鮮,但我正在努力獲得我的OCAJP認證(Java)。 我記得之前讀到過.equals方法可以在我提出這個問題時被覆蓋:

來自Enthuware准備材料的問題:

就我而言,現在這些問題一直很惡劣。 扭曲你認為你知道的每件小事,迫使你學習所有的細枝末節。 現在我猜到了E,但我不認為D是正確的。 當然,我的意思是99.9%,但我認為這是一個基於措辭的技巧問題。

這讓我思考,這是真的嗎? 我的意思是,如果我在考試中得到問題,我現在知道如何回答這個問題,但是在壓倒一切瘋狂的黑暗深淵中,是否有可能創造出a.equals(a)返回false的情況? 我覺得這會讓亞里士多德生氣...

注意a bc是原始包裝類的實例(例如Integer,Double等)。 這些類是final的,無法擴展,因此您無法覆蓋它們的equals實現。

因此a.equals(a)將始終返回true,因為這些類正確地實現了equals

由於equals(...)不是Object的最終方法,是的, 在不同的情況下很可能。

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

然而,這個問題具體說明這些是原始包裝器(例如整數布爾等),並且因為這些類是最終的,所以不能擴展它們,因此a.equals(a)將始終返回true

整數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 ) );
    }
}

其他答案已經回答了你的問題 - 不,這是Java的原始包裝類所不可能的。

我將嘗試解決“問題背后的問題”:這可能與其他課程有關嗎?

[...]在壓倒一切瘋狂的深淵深淵中,是否有可能創造出a.equals(a)返回false的情況? 我覺得這會讓亞里士多德生氣...

這實際上是一個很好的問題,答案是:是的,有可能創造這樣的情況,是的,這會讓亞里士多德生氣。 實際上,我不知道是否會讓亞里士多德生氣,沒有認識他,但對於那些必須使用代碼的人來說肯定會引起很多的悲痛。

問題是:有一個與Object.equals()相關的合同

equals方法在非null對象引用上實現等價關系:

[...]

它是自反的:對於任何非空引用值x,x.equals(x)應該返回true。

Object.equals的Javadocs

是的,在創建自己的課程時,您可以違反此合同。 (遺憾的是)編譯器或運行時中沒有任何內容阻止您。

但是,很多代碼都依賴於這個契約,所以如果你違反它,任何使用equals代碼都可能以神秘的方式失敗。

一個例子:Java自己的Collection類( java.util.Collection和friends)依賴於equals 如果將未正確實現equals的類的實例放入集合中,則會發生奇怪的事情,例如有時包含實例的集合,有時則不會。

您可以查看所有原始包裝器的實現,即:Integer,Boolean,Character等...您將看到實現是正確的。
原因是使用equals,一旦完成檢查就是檢查引用相等性,而x.equals(x)作為對象和參數是同一個對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM