有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java equals方法调用setter,是否有反模式文档?

是否有任何文档说明“equals”方法不应调用“setter”

我只是礼貌地询问~documentation~,而不是意见。满足SOF关于询问意见问题的指导原则

我在oracle文档中没有“看到”它

https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-

public boolean equals(Object obj) Indicates whether some other object is "equal to" this one. The equals method implements an equivalence relation on non-null object references:

It is reflexive: for any non-null reference value x, x.equals(x) should return true.

It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.

It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.

It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified. For any non-null reference value x, x.equals(null) should return false.

The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).

Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

Parameters: obj - the reference object with which to compare. Returns: true if this object is the same as the obj argument; false otherwise. See Also: hashCode(), HashMap


共 (3) 个答案

  1. # 1 楼答案

    这一部分在我看来很突出:它是一致的

    虽然没有说明,但您可以放心地说equals方法应该是不可变的-它不应该改变对象的状态,因为如果状态发生了变化,就不能保证一致性

  2. # 2 楼答案

    测试,如equals,不应有副作用。它们要求是可重入的,可以多次调用,结果相同

    这条规则有一个例外,即记忆、缓存:一种不会泄露给外部世界的局部副作用

    还有一些布尔方法,而不是测试,可以提升状态:当可以读取下一条记录时,ResultSet#next()会产生true

    您将在中找到一些要求,这些要求处理具有已用equals的对象。 例如MapSet当然

    我理解“反模式”你想在equals中的某个地方说明一些规则。最让人想到的是像Sonarint这样的代码风格检查器,它制定并列出了这些规则

  3. # 3 楼答案

    首先,问问你自己-你为什么要这样做然后,找出答案中的错误

    您不需要(而且,大多数情况下,您不会找到)一个文档来列举一些事情,这些事情应该/不能用某个特定实体来完成;相反,文档说明应该做什么和如何做

    是的,上述定义有一些例外,有时文档明确地指出,(1)“您最好避免x!”或(2)“不幸的是您不能做y!”;但这些通常发生在以下情况:(1)一些概念有点模棱两可、模棱两可、重叠/交叉负责,它们可以用多种方式解释;或者(2)当某件事情看起来是可以实现的,一目了然,但事实并非如此

    例如,.equals(Object o)可以是!,但是:

    1. 不应使用获取/设置状态
    2. 不应使用来计算散列
    3. 不应使用执行RPC/Rest调用

    而且这些不应该点(谢天谢地)没有被记录下来,因为自从Java 1.0(1996年1月)以来,.equals(Object o)方法一直有一个单一的、非常明确的责任和目的:断言两个对象的平等性,并且在未来它将继续有同样的唯一目的,由于向后兼容

    .equals(Object o)甚至不应该是推理的问题,我们是否应该使用它来设置状态?,因为对于这一点,setters存在;因此-没有文件证明它可以/不应该用于设置状态;但是,它肯定(!)不应用于设置状态,因为它还有另一个目的,即仅检查this和给定(o)对象的相等性

    此外,在许多情况下,您需要@Override.equals(Object o)对自定义对象进行相应的比较。那么,您将如何在一个方法中混合setter和equals呢?您最终将陷入可维护性和可读性的地狱

    坚持使用Single Responsibility Principle

    坚持干净的代码原则,使您的方法简短、简洁,使用单一、清晰且直观易懂的功能单元

    坚持使用KISS principle,不要试图让你的汽车飞起来,让你的直升机游泳

    考虑类的可读性、可扩展性和可维护性,您可以重写.equals(Object o)来设置状态;那将是地狱。如果我个人看到这样的事情,我会开始怀疑,这段代码的作者是否可以编写getter for setting和setter for get