在Java 中重写equals 和hashCode 时应该考虑哪些问题?

注:本文转自《白煮蛋的博客》  

关于obj.getClass() != getClass().

该语句是equals()继承不友好的结果。JLS(Java 语言规范)指定 if A.equals(B) == truethenB.equals(A)还必须返回true如果您省略该语句,继承覆盖equals()(并更改其行为)的类将破坏此规范。

考虑以下示例,说明省略语句时会发生什么:

    class A {
      int field1;

      A(int field1) {
        this.field1 = field1;
      }

      public boolean equals(Object other) {
        return (other != null && other instanceof A && ((A) other).field1 == field1);
      }
    }

    class B extends A {
        int field2;

        B(int field1, int field2) {
            super(field1);
            this.field2 = field2;
        }

        public boolean equals(Object other) {
            return (other != null && other instanceof B && ((B)other).field2 == field2 && super.equals(other));
        }
    }    

另外new A(1).equals(new A(1))new B(1,1).equals(new B(1,1))结果应该是真实的。

这看起来都很好,但是看看如果我们尝试使用这两个类会发生什么:

A a = new A(1);
B b = new B(1,1);
a.equals(b) == true;
b.equals(a) == false;

显然,这是错误的。

如果要确保对称条件。a=b if b=a 和 Liskov 替换原则super.equals(other)不仅在实例的情况下调用B,而且在实例之后检查A

if (other instanceof B )
   return (other != null && ((B)other).field2 == field2 && super.equals(other)); 
if (other instanceof A) return super.equals(other); 
   else return false;

这将输出:

a.equals(b) == true;
b.equals(a) == true;

如果a不是 的引用B,那么它可能是类的引用A(因为您扩展了它),在这种情况下您也super.equals() 调用.

posted @   small_123  阅读(40)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示