多年来,我一直在处理旧版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等于方法中进行精确比较相关推荐

  1. java中精确地小数_在Java等于方法中进行精确比较

    java中精确地小数 多年来,我一直在处理旧版Java代码,因此遇到了微妙的逻辑和性能问题,这些问题可以追溯到不正确覆盖的Object.equals(Object)方法. 尽管"等于&quo ...

  2. 【Java】方法中的参数传递机制的具体体现

    Java方法中的参数传递机制的具体体现 具体来说是两种:值传递和址传递 以swap(Object obj1,Object obj2)方法为例: 1:如果传递进去的是基本数据类型参数得值,那么再调用sw ...

  3. java 等于_java中的“等于”

    java中的"等于" "==" 和 "equals" 首先来一段代码看看他们的输出情况 public class equals { publ ...

  4. java 在方法中抛出异常_Java异常的抛出

    在Java中,当定义的方法可能产生异常时,程序员必须抛出可能的异常. 抛出异常的两种方式,一是在方法内部用throw语句,二是在方法定义时用throws关键字 1.throw语句 在Java中,thr ...

  5. Java static方法中为什么只能调用静态方法?

    import java.io.*; import java.util.*;public class Main{public static void main(String args[]) throws ...

  6. Java split()方法中的特殊符号

    一.split是什么? 在Java中,split()方法用于分隔字符串,可以根据匹配给定的正则表达式来拆分字符串.split()方法可以将一个字符串分割为子字符串,然后将结果作为字符串数组返回:语法如 ...

  7. 【java】方法中参数列表的应用

    代码清单 package p1;class MethodOverloading {void receive(int i) {System.out.println("Receive one i ...

  8. main方法中args_public static void main(String [] args)– Java main方法

    main方法中args public static void main(String[] args) is the most important Java method. When you start ...

  9. java getbean方法_java main方法中通过ApplicationContext去拿bean(用注解的bean)getbean拿不到?...

    java main方法中通过ApplicationContext去拿bean(用注解的bean)getbean拿不到? 注解类代码如下: ApplicatonContext.xml配置如下: main ...

最新文章

  1. winform 控件半透明设置
  2. 2021高考一诊成绩查询,双流棠湖中学高2021届成都市“一诊”成绩已揭晓
  3. SAP S/4HANA里KPI tile的一个具体例子
  4. oracle xml中cdata,XML CDATA的作用
  5. session案例之验证码
  6. Codeforces Global Round 13 C
  7. pthread和互斥量条件变量函数意义速查表
  8. 浙大 PAT a1027
  9. ijkplayer android端jni层调试
  10. 房产中介管理系统php,房屋中介管理系统简易源代码.doc
  11. 你听过“费斯汀格法则”吗?多少人因为不懂而被残害!好文!
  12. 知我者谓我心忧,不知我者谓我何求
  13. java8新特性之---全新的日期、时间API(JSR 310规范),附SpringMVC、Mybatis中使用JSR310的正确姿势
  14. 读just spring(一)(翻译的不好,都是用自己的话)
  15. 中职网络安全隐藏信息探索思路以及讲解
  16. neovim初始化以及插件安装
  17. 李宏毅-机器学习-RNN-笔记
  18. 使用pytorch搭建自己的网络之Res2Net
  19. linux命令--mkdir 与文件权限
  20. 沐圣moolsun:做真正的民族品牌

热门文章

  1. 聚集索引、辅助索引、覆盖索引、联合索引
  2. JavaWeb的web.xml标签元素(一)
  3. Spring Enable*高级应用及原理
  4. ssm使用全注解实现增删改查案例——Emp
  5. hibernate注解实体类(Dept.java)
  6. React类里面能写的东西
  7. 2020蓝桥杯省赛---java---B---2(寻找 2020)+测试txt
  8. 使用Jersey跨服务器上传图片 报405 Method Not Allowed错误
  9. HBase体系架构说明
  10. pivot sqlserver 条件_行转列之SQLSERVERPIVOT与用法详解