• 重写equals的问题


       我们都知道,在比较两个对象是否相同时,会用到equals方法,比如Listcontains方法,就会调用比较对象的equals方法。前段时间在公司写的一个文件查看小工具,就用到了equals这个方法。具体是遍历两个现个文件夹,如果名称相同的话,比较它们的文件大小,大小不同的话就列举出来。

       由于不精通算法。就用了土方法。遍历两个指定的文件夹,把拿到的文件对象存到两条列表中。再对一个列表进行遍历,然后用List的contains判断是否是符合要求的文件,是的话就存到另外一个List,最后返回出去。

           

    List<FileEntity> a_files = getFiles("a_floder");//遍历两个指定的文件夹,把拿到的文件对象存到两条列表中
    List<FileEntity> b_files = getFiles("b_floder");
    List<FileEntity> files = new ArrayList<FileEnityt>();//存同名,不同大小文件的
    for(FileEntity f:a_files){
        if(b_files.contains(f)){//这里的contains就是调用了FileEntity的equals方法,所以我重写了FileEntity的equals方法
          files.add(f);
        }
    
    }

    下面是我FileEntity类重写equals方法

    public class FileEntity{
    
       //省略属性的定义
    
      @Override
       public boolean equals(Object obj){
              if(!(obj instanceof FileEntity)){//    这里可能出现问题   
                    return false;
              }else{
                    FileEntity f = (FileEntity)obj;
                    if(this.name.equals(f.name)&&this.size!=f.size){//名字相同,大小不同
                         return true;
                    }else{
                         return false;
                    }
              }
    
       }
    
    }

         由于重写了FileEntity的equals方法,所以 b_files.contains(f)这句代码就会调用FileEntity的equals方法,按自己重写的方法进行比较。

         但是这里想说的就是,用instanceof有可能出现问题。

         因为 a instanceof b  (如果b是a的父类,也是返回true的),比如下面的代码就会出现问题了。假设Employee继承自Person

        

    @Override       
    public boolean equals(Object obj) {
                if(obj instanceof Employee){
                  Employee e = (Employee) obj;
                  return super.equals(obj)&& e.getId() == id;//id相同就是同一个人            
                }
                return false;       
    }  

    如果我们写

    Person p = new Person(15);//id为15的人
    Employee ep1 = new Employee(15);//id为15的员工
    Employee ep2 = new Employee(15);//id为15的员工
    Employee ep3 = new Employee(16);//id为16的员工
    
    ep1.equals(eq2);//结果为true,这个是可以接受的
    p.equals(ep1);//这个结果也为true,我们期望的应该是false.因为id为15的人不一定是id为15的员工

    上面的问题就是出在 p.equals(ep1)调用的是父类Person的equals方法。而父类的equals方法有   obj instanceof Person,员工也是人,所以返回的是true,又因为id相同,所就equals返回的就是true了。

    因父类使用了instanceof关键字来判断是否是一个类的实例对象的,这很容易让子类“钻空子”,为了避免这个问题,应该使用getClass来代替instanceof进行类型判断,改变后的代码如下,

    if(obj instanceof Employee)
    //用下面这各种方法避免上面提到的问题
    if(this.getClass()==obj.getClass())
  • 相关阅读:
    内存溢出
    接手新业务
    pjb fabu
    中文手册
    人背的时候,做啥都失败
    帮助开发人员学习
    python中的__dict__,__getattr__,__setattr__
    NetCore在Docker中发布及运行
    ELK基础配置
    IdentityServer4 手动验签及日志记录
  • 原文地址:https://www.cnblogs.com/baron89/p/2795917.html
Copyright © 2020-2023  润新知