当前位置: 代码迷 >> Java相关 >> (分享)学习Java应注意的一些细节(三)
  详细解决方案

(分享)学习Java应注意的一些细节(三)

热度:64   发布时间:2009-10-17 16:20:35.0
(分享)学习Java应注意的一些细节(三)
3,怎样的equals才安全?
    我们都知道在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,只要这两个对象有相同的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的任何子类的实例
搜索更多相关的解决方案: 学习  分享  细节  Java  

----------------解决方案--------------------------------------------------------
  相关解决方案