.equals(String.equals)与object.eq

2018-10-08  本文已影响0人  熨斗目花

基本上是抄的,只做笔记。

讲在最前面

equals方法必须具备以下特性

自反性(x.equals(x)返回true)、对称性(若x.equals(y)返回true则y.equals(x)返回true)、传递性(若x.equals(y)返回true且y.equals(z)返回true,则x.equals(z)应当返回true)、一致性(若x,y未改变,则反复调用x.equals(y)返回值应当相同)、对任意的非空引用x.equals(null)应返回false

e.quals(m) e是Employee的一个对象而m是Manager的一个对象,两者姓名薪水上岗日期均完全相同。若在重写的.equals方法中利用 instanceof 比较类名则会出现问题。

(抄)

网上流行的getClass()版本:

public class Student {
private String name;
public boolean equals(Object object){
if (object == this)
return true;
// 使用getClass()判断对象是否属于该类
if (object == null || object.getClass() != getClass())
return false;
Student student = (Student)object;
return name != null && name.equals(student.name);
}

网上流行的instanceof版本

public class Student {
private String name;
public boolean equals(Object object){
if (object == this)
return true;
// 通过instanceof来判断对象是否属于类
if (object == null || !(object instanceof Student))
return false;
Student student = (Student)object;
return name!=null && name.equals(student.name);
}
}

事实上两种方案都是有效的,区别就是getClass()限制了对象只能是同一个类,而instanceof却允许对象是同一个类或其子类。我要说的其实不是这个,你再看看下面这个instanceof 版本

public class Student {
####private String name;
public boolean equals(Object object){
if (object == this)
return true;
// 通过instanceof来判断对象是否属于类
if (object == null || !(object instanceof Student))
return false;
Student student = (Student)object;
// 跟上个instanceof版本唯一不同的是,这里使用student.getName()而不是student.name
return name!=null && name.equals(student.getName());
}
}

你会发现,如果将name.equals(student.name);改为name.equals(student.getName());或getName().equals(student.getName());都不规范。原因:
假设GoodStudent extends Student。

Student student=new Student();
GoodStudent goodstudent=new GoodStudent();
student.setName("some");
goodstudent.setName("some");

因为name是private修饰的。参数goodstudent是GoodStudent类,而当main方法在父类中进行时,假如equals的调用者是Student类,而参数student如果是GoodStudent类,由于name属性对其它类不可见,不论是否有值,student.name为null,所以equals返回false。

你只能在尾行书写:
getName().equals(student.getName());
这样equals方法就变成了父类与子类也可进行equals操作了,只要name属性的值一样。按照各自的业务可以有各自的equals实现,但是按照规范来说,equals不应该是父类与子类对象可以进行的操作,所以重写equals方法应当选用getClass()来进行判断对象是否属于类,而不应该用instanceof,后者会让子类钻漏洞。

如果你写:
String a1="abc";
String b1="abc";
a1==b1返回true。

但是如果你写:
String a2=new String("abc");
String b2=new String("abc");
a2==b2将返回false。

总结:

Object.equals相等,String.equals一定相等;

String.equals相等,Object.equals不一定相等。

需要格外强调的是,你比较类的时候,虚拟机知道你传的参是object(类)类,所以会自行调用Object.equals的比较法。也就是说比较地址。所以使用时建议重写。

但是!重写.equals必须重写hashcode!

我还是没懂。
nstanceof进行类型检查规则是:你属于该类吗?或者你属于该类的派生类吗?而通过getClass获得类型信息采用==来进行检查是否相等的操作是严格的判断。不会存在继承方面的考虑
大概就是father1 instanceof father T
child instanceif father T
但是
child.getClass()==father1.getClass() F

上一篇下一篇

猜你喜欢

热点阅读