A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

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

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1

查看全部评分

1 个回复

倒序浏览
那如果我用子类调用父类的方法,然后再传进去一个父类对象呢?结果会怎么样?你只考虑了传进去的对象,没有考虑调用该方法的对象。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马