基本类型,比较值是否相等 引用类型,比较内存地址值是否相等 不能比较没有父子关系的两个对象
JDK 中的类一般已经重写了 equals(),比较的是内容。 自定义类如果没有重写 equals(),将调用父类(默认 Object 类)的 equals() 方法
// object类中的equals() 方法 public boolean equals(Object obj) { return (this == obj); }Object 的 equals() 比较使用了 this == obj,可以按照需求逻辑,重写对象的 equals() 方法(重写 equals 方法,一般须重写 hashCode 方法)
下面给出编写一个完美的 equals 方法的建议: 1 ) 显式参数命名为 otherObject, 稍后需要将它转换成另一个叫做 other 的变量。
2 ) 检测 this 与 otherObject 是否引用同一个对象: if (this == otherObject) return true; 这条语句只是一个优化。实际上,这是一种经常采用的形式。因为计算这个等式要比一个一个地比较类中的域所付出的代价小得多。
3 ) 检测 otherObject 是否为 null, 如 果 为 null, 返 回 false。这项检测是很必要的。 if (otherObject == null) return false;
4 ) 比较 this 与 otherObject 是否属于同一个类。如果 equals 的语义在每个子类中有所改变,就使用 getClass 检测: if (getClass() != otherObject.getCIass() ) return false;
如果所有的子类都拥有统一的语义,就使用 instanceof 检测: if (!(otherObject instanceof ClassName)) return false;
5 ) 将 otherObject 转换为相应的类类型变量: ClassName other = (ClassName) otherObject
6 ) 现在开始对所有需要比较的域进行比较了。使用 == 比较基本类型域,使用 Objects.equals 比较对象域。如果所有的域都匹配, 就返回 true; 否 则 返 回 false。
return field 1 == other.field 1 && Objects.equa1s(field2, other.field2) && … ; 如果在子类中重新定义 equals, 首先调用超类的 equals。如果检测失败, 对象就不可能相等。如果超类中的域都相等, 就需要比较子类中的实例域。
public class Manager extends Employee public boolean equals(Object otherObject) { if (!super.equals(otherObject)) return false; // super.equals checked that this and otherObject belong to the same class Manager other = (Manager) otherObject; return bonus == other.bonus; } }两个API:
优化了Object的equals方法比较时的空指针异常
这是java.util.Objects类中的一个方法:
在JDK7添加了一个Objects工具类,它提供了一些方法来操作对象,它由一些静态的实用方法组成,这些方法是null-save(空指针安全的)或null-tolerant(容忍空指针的),用于计算对象的hashcode、返回对象的字符串表示形式、比较两个对象。
在比较两个对象的时候,Object的equals方法容易抛出空指针异常,而Objects类中的equals方法就优化了这个问题。方法如下:
public static boolean equals(Object a, Object b):判断两个对象是否相等。我们可以查看一下源码,学习一下:
public static boolean equals(Object a, Object b) { return (a == b) || (a != null && a.equals(b)); }使用规则:
如果子类能够拥有自己的相等概念, 则对称性需求将强制采用 getClass 进行检测如果由超类(父类)决定相等的概念,那么就可以使用 imtanceof进行检测, 这样可以在不同子类的对象之间进行相等的比较。getClass和instanceof的区别
instanceof进行类型检查规则是:你属于该类吗?或者你属于该类的派生类吗?通过getClass获得类型信息采用==来进行检查是否相等的操作是严格的判断。不会存在继承方面的考虑;显示getClass和instanceof的区别的测试:
public class Test { public static void testInstanceof(Object x) { System.out.println("x instanceof Parent: "+(x instanceof Parent)); System.out.println("x instanceof Child: "+(x instanceof Child)); System.out.println("x getClass Parent: "+(x.getClass() == Parent.class)); System.out.println("x getClass Child: "+(x.getClass() == Child.class)); } public static void main(String[] args) { testInstanceof(new Parent()); System.out.println("---------------------------"); testInstanceof(new Child()); } } class Parent { } class Child extends Parent { } /* 输出: x instanceof Parent: true x instanceof Child: false x getClass Parent: true x getClass Child: false --------------------------- x instanceof Parent: true x instanceof Child: true x getClass Parent: false x getClass Child: true */ps: final 修饰类中的方法
说明这种方法提供的功能已经满足当前要求,不需要进行扩展,并且也不允许任何从此类继承的类来重写这种方法,但是继承仍然可以继承这个方法,也就是说可以直接使用。在声明类中,一个 final 方法只被实现一次。