[英]Can .equals be overridden such that a.equals(a) returns false?
注意a
。 b
和c
是原始包裝類的實例(例如Integer,Double等)。 這些類是final的,無法擴展,因此您無法覆蓋它們的equals
實現。
因此a.equals(a)
將始終返回true,因為這些類正確地實現了equals
。
由於equals(...)
不是Object
的最終方法,是的, 在不同的情況下很可能。
@Override
public boolean equals(Object obj) {
return false;
}
然而,這個問題具體說明這些是原始包裝器(例如整數 , 布爾等),並且因為這些類是最終的,所以不能擴展它們,因此a.equals(a)
將始終返回true
。
但你必須非常邪惡並使用反射和多線程:
如果您運行此代碼,則在比較發生時,競賽條件可能會更改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。
是的,在創建自己的課程時,您可以違反此合同。 (遺憾的是)編譯器或運行時中沒有任何內容阻止您。
但是,很多代碼都依賴於這個契約,所以如果你違反它,任何使用equals
代碼都可能以神秘的方式失敗。
一個例子:Java自己的Collection類( java.util.Collection
和friends)依賴於equals
。 如果將未正確實現equals
的類的實例放入集合中,則會發生奇怪的事情,例如有時包含實例的集合,有時則不會。
您可以查看所有原始包裝器的實現,即:Integer,Boolean,Character等...您將看到實現是正確的。
原因是使用equals,一旦完成檢查就是檢查引用相等性,而x.equals(x)作為對象和參數是同一個對象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.