美文网首页
.equals(String.equals)与object.eq

.equals(String.equals)与object.eq

作者: 熨斗目花 | 来源:发表于2018-10-08 20:31 被阅读0次

    基本上是抄的,只做笔记。

    讲在最前面

    equals方法必须具备以下特性

    自反性(x.equals(x)返回true)、对称性(若x.equals(y)返回true则y.equals(x)返回true)、传递性(若x.equals(y)返回true且y.equals(z)返回true,则x.equals(z)应当返回true)、一致性(若x,y未改变,则反复调用x.equals(y)返回值应当相同)、对任意的非空引用x.equals(null)应返回false

    • 我先开始觉得对称性就是一句废话,我认为理所当然,但是有这么个例子:

    e.quals(m) e是Employee的一个对象而m是Manager的一个对象,两者姓名薪水上岗日期均完全相同。若在重写的.equals方法中利用 instanceof 比较类名则会出现问题。

    (抄)

    网上流行的getClass()版本:

    public class Student {
    private String name;
    public boolean equals(Object object){
    if (object == this)
    return true;
    // 使用getClass()判断对象是否属于该类
    if (object == null || object.getClass() != getClass())
    return false;
    Student student = (Student)object;
    return name != null && name.equals(student.name);
    }

    网上流行的instanceof版本

    public class Student {
    private String name;
    public boolean equals(Object object){
    if (object == this)
    return true;
    // 通过instanceof来判断对象是否属于类
    if (object == null || !(object instanceof Student))
    return false;
    Student student = (Student)object;
    return name!=null && name.equals(student.name);
    }
    }

    事实上两种方案都是有效的,区别就是getClass()限制了对象只能是同一个类,而instanceof却允许对象是同一个类或其子类。我要说的其实不是这个,你再看看下面这个instanceof 版本

    public class Student {
    ####private String name;
    public boolean equals(Object object){
    if (object == this)
    return true;
    // 通过instanceof来判断对象是否属于类
    if (object == null || !(object instanceof Student))
    return false;
    Student student = (Student)object;
    // 跟上个instanceof版本唯一不同的是,这里使用student.getName()而不是student.name
    return name!=null && name.equals(student.getName());
    }
    }

    你会发现,如果将name.equals(student.name);改为name.equals(student.getName());或getName().equals(student.getName());都不规范。原因:
    假设GoodStudent extends Student。

    Student student=new Student();
    GoodStudent goodstudent=new GoodStudent();
    student.setName("some");
    goodstudent.setName("some");

    • 重写方法尾行采用name.equals(student.getName()):
      调用方法goodstudent.equals(student)返回false
      调用方法student.equals(goodstudent)返回true

    • 重写方法尾行采用 getName().equals(student.name)
      调用方法goodstudent.equals(student))返回true
      调用方法student.equals(goodstudent))返回false

    • 重写方法尾行采用name.equals(student.name)
      反正还是有问题。

    因为name是private修饰的。参数goodstudent是GoodStudent类,而当main方法在父类中进行时,假如equals的调用者是Student类,而参数student如果是GoodStudent类,由于name属性对其它类不可见,不论是否有值,student.name为null,所以equals返回false。

    你只能在尾行书写:
    getName().equals(student.getName());
    这样equals方法就变成了父类与子类也可进行equals操作了,只要name属性的值一样。按照各自的业务可以有各自的equals实现,但是按照规范来说,equals不应该是父类与子类对象可以进行的操作,所以重写equals方法应当选用getClass()来进行判断对象是否属于类,而不应该用instanceof,后者会让子类钻漏洞。

    • Object.equals(==):比较内存地址;基本数据类型(储存在栈中)用它比较就行。
      特别要说的是,关于字符串。

    如果你写:
    String a1="abc";
    String b1="abc";
    a1==b1返回true。

    但是如果你写:
    String a2=new String("abc");
    String b2=new String("abc");
    a2==b2将返回false。

    • String.equals: 比较内容即可,不管内存地址。
      也就是说,a2.equals(b2)返回true。

    总结:

    Object.equals相等,String.equals一定相等;

    String.equals相等,Object.equals不一定相等。

    需要格外强调的是,你比较类的时候,虚拟机知道你传的参是object(类)类,所以会自行调用Object.equals的比较法。也就是说比较地址。所以使用时建议重写。

    但是!重写.equals必须重写hashcode!

    我还是没懂。
    nstanceof进行类型检查规则是:你属于该类吗?或者你属于该类的派生类吗?而通过getClass获得类型信息采用==来进行检查是否相等的操作是严格的判断。不会存在继承方面的考虑
    大概就是father1 instanceof father T
    child instanceif father T
    但是
    child.getClass()==father1.getClass() F

    相关文章

      网友评论

          本文标题:.equals(String.equals)与object.eq

          本文链接:https://www.haomeiwen.com/subject/olijaftx.html