最近在看core Java,里面涉及到的对于编写equals方法以及继承时,可能会发生的错误做出了详细的介绍,看完后觉得有点意外,因为在看教学视频时,并没有涉及到如此多的重点,现在将要点提取出来整理如下:
Java语言对于equals方法的要求如下:
△自反性:对于任何非空引用x,x.equals(x)应该返回true
△对称性:对于任何引用x和y,当且仅当x.equals(y)返回true,y.equals(x)也可以返回true.
△传递性:对于任何引用x,y和z,x.equals(y)返回true,y.equals(z)返回ture,那么x.equals(z)返回true.
△一致性:如果x和y引用的对象没有发生变化,反复调用x.equals(y)应该返回同样的结果.
△x.equals(null)应当返回false.
一个正确严谨的equals方法应该满足以上五个特性,那么可以从两个情况进行分析:
1).如果子类能够拥有自己相等的概念,则对称性要求强制采用getClass进行检测
2).如果由超类决定相等的概念,那么可以使用instanceOf进行检测,这样可以在不同子类对象之间进行相等的比较,同时将超类的equals方法设置为final.
现在用两个小事例说明一下观点:
1)子类可以拥有自己的新特性时,父类equals方法的编写,这里子类复写的方法几乎完全相同,在此省略、另外为了代码简洁,没有重写get,set方法。
//演示子类可以拥有自己的特性存在时候equals方法的编写 class Car { private String name; private int color; public Car(String name, int color) { super(); this.name = name; this.color = color; } @Override public int hashCode() { return Objects.hash(name,color); //根据Java7新特性,便捷的复写hashcode方法. } @Override public boolean equals(Object obj) { if(obj==null) return false; //x.equals(null)需要返回false if(this==obj) return true; //x.equals(x)需要返回true if(this.getClass()!=obj.getClass()) return false;//不是同一个类的对象,返回false //此时确定obj和this是同一个运行时对象. Car other=(Car)obj; return this.name.equals(other.name)&&this.color==other.color; } }
2)由超类决定相等的概念的情况下,equals方法的复写。
//演示超类决定相等概念的时候equals方法的编写 class Car { private String name; private int color; public Car(String name, int color) { super(); this.name = name; this.color = color; } @Override public int hashCode() { return Objects.hash(name,color); //根据Java7新特性,便捷的复写hashcode方法. } @Override public final boolean equals(Object obj) { if(obj==null) return false; //x.equals(null)需要返回false if(this==obj) return true; //x.equals(x)需要返回true if(obj instanceof Car) return false;//超类不是Car,返回false //此时确定obj和this是同一个超类. Car other=(Car)obj; return this.name.equals(other.name)&&this.color==other.color; } }