在Java等于方法中进行精确比较
多年來,我一直在處理舊版Java代碼,因此遇到了微妙的邏輯和性能問題,這些問題可以追溯到不正確覆蓋的Object.equals(Object)方法。 盡管“等于”方法背后的概念看似簡單,但Josh Bloch在《 有效Java》中指出:“重寫equals方法似乎很簡單,但是有很多方法可以弄錯它,其后果可能是可怕的。 避免問題的最簡單方法是不重寫equals方法,在這種情況下,每個實例僅等于其自身。” 在這篇文章中,我看了一種使equals(Object)錯誤的“許多方法”之一:無法完全比較被評估是否相等的兩個對象的完全相同的特征。
下一個代碼清單是針對MismatchedFieldAccessor類的。 此類的equals(Object)方法有缺陷,因為它將類的直接屬性someString與從另一個對象的getSomeString()檢索的值進行比較。 在大多數Java類中,將類的字段與其訪問器/獲取方法進行比較將可以正常工作,因為訪問器/獲取方法僅返回相關的字段。 但是,在此示例類中,accessor / get方法的作用不只是簡單地返回該字段,而且還使該字段與equals(Object)方法中的get / accessor方法的比較不一致。 (請注意,此處不建議使用“ get”方法來執行此類操作,只是作為一個易于理解的示例而存在。)
package dustin.examples.brokenequals;import java.util.Objects;/*** Demonstrate problem with mismatched field/accessor in* overridden equals(Object) implementation.*/ public final class MismatchedFieldAccessor {private final String someString;public MismatchedFieldAccessor(final String newString){someString = newString;}public String getSomeString(){return someString != null ? someString : "";}@Overridepublic boolean equals(final Object other){if (this == other){return true;}if (other == null || getClass() != other.getClass()){return false;}final MismatchedFieldAccessor that = (MismatchedFieldAccessor) other;return Objects.equals(this.someString, that.getSomeString());}@Overridepublic int hashCode(){return someString != null ? someString.hashCode() : 0;} }如果使用適當的單元測試進行測試,上述類將失敗。 下一個代碼清單中列出的兩個單元測試指出了類的equals方法的問題。
public void testEqualsOnConstructedWithNull() {final MismatchedFieldAccessor accessor = new MismatchedFieldAccessor(null);Assert.assertEquals(null, accessor.getSomeString()); }@Test public void testEqualsWithEqualsVerifier() {EqualsVerifier.forClass(MismatchedFieldAccessor.class).verify(); }上面顯示的第一個單元測試失敗,并顯示以下消息:
java.lang.AssertionError: Expected :null Actual :第二個單元測試利用方便的EqualsVerifier庫來確定此equals(Object)實現的問題(已添加重點 ):
java.lang.AssertionError: Reflexivity: object does not equal an identical copy of itself:dustin.examples.brokenequals.MismatchedFieldAccessor@0 If this is intentional, consider suppressing Warning.IDENTICAL_COPY For more information, go to: http://www.jqno.nl/equalsverifier/errormessagesat nl.jqno.equalsverifier.EqualsVerifier.handleError(EqualsVerifier.java:381)at nl.jqno.equalsverifier.EqualsVerifier.verify(EqualsVerifier.java:367)at dustin.examples.brokenequals.MismatchedFieldAccessorTest.testEqualsWithEqualsVerifier(MismatchedFieldAccessorTest.java:36)如果不認真執行,檢查和測試, equals方法可能會變壞,這是許多方法之一。 幸運的是,解決此特定問題的方法很容易:始終將要比較的兩個實例的相同字段或相同方法的返回對象進行比較,以確保相等。 在本文中使用的示例中,直接比較兩個“ someString”字段將使“ equals”方法正常工作。
翻譯自: https://www.javacodegeeks.com/2016/12/compare-exactly-java-equals-methods.html
總結
以上是生活随笔為你收集整理的在Java等于方法中进行精确比较的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 摩尔线程完成虚幻引擎 5 在国产显卡上的
- 下一篇: mountain_OS X Mounta