您的位置:首页 > 教育 > 培训 > 推广一般收多少钱_百度搜索引擎优化相关性评价_站长工具seo综合查询收费吗_网络营销软件

推广一般收多少钱_百度搜索引擎优化相关性评价_站长工具seo综合查询收费吗_网络营销软件

2026/1/2 23:49:03 来源:https://blog.csdn.net/nokiaguy/article/details/142620809  浏览:    关键词:推广一般收多少钱_百度搜索引擎优化相关性评价_站长工具seo综合查询收费吗_网络营销软件
推广一般收多少钱_百度搜索引擎优化相关性评价_站长工具seo综合查询收费吗_网络营销软件

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界

重写 equals 方法看似简单,但极易出错,且后果严重。要避免问题,最简单的方法就是不重写 equals,这样每个类的实例只与自身相等。如果以下情况适用,那么不重写 equals 是正确的选择:

  1. 类的每个实例都是独一无二的:例如 Thread 类,其代表的是活跃实体,而不是值,默认的 equals 方法已经适用。
  2. 类不需要逻辑上的相等性测试:例如 Pattern 类可以重写 equals 来检查两个正则表达式是否相同,但设计者认为不需要这个功能。
  3. 超类已经重写了 equals 并且该行为适用于子类:例如,大多数 Set 实现继承自 AbstractSetequalsList 实现继承自 AbstractListMap 实现继承自 AbstractMap
  4. 类是私有或包私有的,且你确定 equals 不会被调用:可以通过重写 equals 方法抛出 AssertionError 来确保该方法不会被意外调用。

何时应该重写 equals

当类有逻辑上的相等性要求且超类没有重写 equals 时,就应该重写。通常这是值类的情况,例如 IntegerString。程序员期望通过 equals 比较这些值类的逻辑等价性,而不是对象的引用是否相同。重写 equals 方法不仅是为了满足程序员的预期,也是为了让实例在作为键或集合元素时表现一致且可预测。

不需要重写 equals 的情况之一是使用实例控制(【条目1】)确保每个值最多只有一个对象。例如 Enum 类型,因为逻辑等价就是对象标识,Objectequals 方法已足够。

equals 合同

重写 equals 时,必须遵循 equals 的一般合同。合同规定 equals 实现等价关系,具体包括以下五个属性:

  1. 自反性:对于任何非空引用值 xx.equals(x) 必须返回 true
  2. 对称性:对于任何非空引用值 xyx.equals(y) 必须返回与 y.equals(x) 相同的结果。
  3. 传递性:如果 x.equals(y) 为真,且 y.equals(z) 为真,那么 x.equals(z) 必须为真。
  4. 一致性:只要 equals 比较中使用的信息没有被修改,x.equals(y) 的多次调用必须始终返回相同的结果。
  5. 非空性:对于任何非空引用值 xx.equals(null) 必须返回 false

这些要求听起来复杂,但理解后不难遵守。如果违反合同,可能导致程序行为不稳定,甚至崩溃,且错误源头难以定位。

详细解释 equals 合同

自反性

自反性要求对象必须与自身相等。违反这一要求很少见。如果违反它,可能导致集合中的 contains 方法无法找到刚添加的对象。

对称性

对称性要求两个对象必须对其相等性意见一致。例如,以下类实现了一个忽略大小写的字符串:

// 错误示例 - 违反对称性
public final class CaseInsensitiveString {private final String s;public CaseInsensitiveString(String s) {this.s = Objects.requireNonNull(s);}@Override public boolean equals(Object o) {if (o instanceof CaseInsensitiveString)return s.equalsIgnoreCase(((CaseInsensitiveString) o).s);if (o instanceof String)return s.equalsIgnoreCase((String) o);return false;}
}

上面的 equals 方法试图与普通字符串互操作,但这导致了对称性问题:cis.equals(s) 返回 true,而 s.equals(cis) 返回 false。为解决此问题,可以去掉与 String 的互操作代码:

@Override public boolean equals(Object o) {return o instanceof CaseInsensitiveString &&((CaseInsensitiveString) o).s.equalsIgnoreCase(s);
}
传递性

传递性要求如果 x.equals(y) 为真且 y.equals(z) 为真,那么 x.equals(z) 也必须为真。考虑扩展类 Point 添加颜色属性的场景:

public class ColorPoint extends Point {private final Color color;public ColorPoint(int x, int y, Color color) {super(x, y);this.color = color;}@Override public boolean equals(Object o) {if (!(o instanceof ColorPoint))return false;return super.equals(o) && ((ColorPoint) o).color == color;}
}

此方法违反了对称性和传递性:p.equals(cp) 返回 true,而 cp.equals(p) 返回 false。为解决此问题,使用组合而不是继承:

public class ColorPoint {private final Point point;private final Color color;public ColorPoint(int x, int y, Color color) {point = new Point(x, y);this.color = Objects.requireNonNull(color);}@Override public boolean equals(Object o) {if (!(o instanceof ColorPoint))return false;ColorPoint cp = (ColorPoint) o;return cp.point.equals(point) && cp.color.equals(color);}
}
一致性

一致性要求对象在未被修改时,相等性必须一致。如果类是可变的,则要确保修改后 equals 的结果也保持一致。

非空性

对象必须与 null 不相等。即使传递 nullequals 返回 false,也不应抛出 NullPointerException。这可以通过 instanceof 检查来实现。

编写高质量的 equals 方法

  1. 使用 == 检查参数是否为当前对象。
  2. 使用 instanceof 检查参数类型。
  3. 将参数转换为正确类型。
  4. 比较所有“重要”字段,确保它们的值相等。

结论

不应轻易重写 equals,除非有必要。如果需要重写,务必确保比较类的所有重要字段,并遵守 equals 合同的五个规定。对于复杂的值比较,应考虑使用组合而非继承。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com