今天在网上无意中看到关于equals安全性的文章,和大家分享一下。
首先看下面的代码- class Student{
- private String name;
- private int age;
- public Student(String name,int age){
- this.name=name;
- this.age=age;
- }
- public boolean equals(Object obj){
- if(obj instanceof Student){
- Student s=(Student)obj;
- if(s.name.equals(this.name) && s.age==this.age){
- return true;
- }
- }
- return super.equals(obj);
- }
- }
复制代码 你认为上面的代码equals方法的覆盖安全吗?表面看起来好像没什么问题,这样写也确实满足了以上的五大原则。但其实这样的覆盖并不很安全,假如Student类还有一个子类CollegeStudent,如果我拿一个Student对象和一个CollegeStudent对象equals,只要这两个对象有相同的name和age,它们就会被认为相等,但实际上它们是两个不同类型的对象啊。问题就出在instanceof这个运算符上,因为这个运算符是向下兼容的,也就是说一个CollegeStudent对象也被认为是一个Student的实例。怎样去解决这个问题呢?那就只有不用instanceof运算符,而使用对象的getClass()方法来判断两个对象是否属于同一种类型,例如,将上面的equals()方法修改为:- public boolean equals(Object obj){
- if(obj.getClass()==Student.class){
- Student s=(Student)obj;
- if(s.name.equals(this.name) && s.age==this.age){
- return true;
- }
- }
- return super.equals(obj);
- }
- }
复制代码 这样才能保证obj对象一定是Student的实例,而不会是Student的任何子类的实例 |