怎样重写equals方法才安全?

本文探讨了Java中equals方法的正确覆写方式,特别是如何避免由instanceof运算符带来的子类实例匹配问题,提出了使用getClass方法进行精确类型检查的解决方案。

    我们都知道在Java规范里定义了equals方法覆盖的5大原则:reflexive(自反性),symmetric(对称性),transitive(传递性),consistent(一致性),non-null(非空性)。我们看一下下面的代码:

public 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,只要这两个对象有相同的nameage,它们就会被认为相等,但实际上它们是两个不同类型的对象啊。问题就出在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的任何子类的实例。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值