equals()规范,假设对象都不为null:
- 自反性:x.equals(x)->true
- 对称性:x.equals(y)<->y.equals(x)
- 传递性:x.equals(y) and y.equals(z) ->x.equals(z)
- 一致性:当x与y对象内容未改变时,x.equals(y)的值永远不变
- 非空性:x.equals(null)->false
重写equals()分为5步:
- this==obj判断同一引用直接返回true
- obj==null判断obj为null直接返回false(因为能调用equals就表明this不为null,两者不相等)
- getClass或者instanceof判断是否属于同一类(涉及继承需分情况选择)
- 将obj参数转换为当前类
- 对比各个域的值是否相等(若成员是对象则应该使用Objects.equals(Field1,Field2)来判断是否相等,避免其中有一个是null造成的异常)
举例:Manager类(int bonus;String sex),可继承Person类(String name)
getClass与instanceof对比
getClass:精确判断对象的类型
instanceof:判断是否是某类型,可以是父类或者接口
Manager instanceof Person ->true(Manager也是Person)
Person instanceof Manger->false(不是每个Person都是Manager)
没有继承Person类,直接继承Object类
个人定义equals的意义,任意选择getClass或instanceof来实现对比是否属于同一类
@Override public boolean equals(Object obj) { //1.如果引用相同的对象直接返回true if(this==obj)return true; //2.因为能够调用equals则表明this不为null,所以如果obj为null,直接返回false if(obj==null)return false; //3.判断是否同一类 if(getClass()!=obj.getClass())return false; if(!(obj instanceof Manager))return false; //4.将obj强制类型转换为当前类型 Manager object=(Manager)obj; //5.调用父类对象的equals与子类特有域一一对比,因为对象如String要使用equals所以要采用Objects.equals(field1,field2)来对比 return Objects.equals(this.sex,object.sex) &&this.bonus==object.bonus; }
继承Person类
若是子类Manager有自己的相等概念定义,则强制使用getClass规定类型精确相等
@Override public boolean equals(Object obj) { //1.如果引用相同的对象直接返回true if(this==obj)return true; //2.因为能够调用equals则表明this不为null,所以如果obj为null,直接返回false if(obj==null)return false; //3.判断类型相等 if(getClass()!=obj.getClass())return false;//4.将obj强制类型转换为当前类型 Manager object=(Manager)obj; //5.调用父类对象的equals并且子类特有域一一对比,因为对象如String要使用equals所以要采用Objects.equals(field1,field2)来对比 return super.equals(obj) &&Objects.equals(this.sex,object.sex) &&this.bonus==object.bonus; }
若是由父类Person定义相等的概念,则可以使用instanceof进行检测,这样Person的不同子类之间都可以比较;
同时父类将该方法设为final使得子类不能重写
@Override public final boolean equals(Object obj) { //1.如果引用相同的对象直接返回true if(this==obj)return true; //2.因为能够调用equals则表明this不为null,所以如果obj为null,直接返回false if(obj==null)return false; //3.精确要求类型相等 if(getClass()!=obj.getClass())return false; //3.判断类型是否相等(同一继承链) if(!(obj instanceof Person))return false; //4.将obj强制类型转换为当前类型 Person object=(Person) obj; //5.调用父类对象的equals与子类特有域一一对比,因为对象如String要使用equals所以要采用Objects.equals(field1,field2)来对比 return Objects.equals(Field,Field) }