今天学习了Object类,它是所有类的超类,他其中有一个很重要的方法equals方法。我们都知道两个对象进行比较,如果是基本数据类型,那么比较的是两个数的值是否相等,而对象比较的是地址值,如果没有重写equals方法,那么默认使用父类Object的equals方法,这个方法内部默认使用==进行对象的比较,但是我们知道对象是引用类型,而引用类型比较的是地址值,每个对象的地址值是不同的,所以equals方法无论如何都是返回的false,那么我们使用这个方法就没有意义了,所以我们需要重写equals方法,通过判断对象的属性的值是否相同来判断对象是否相等。
public boolean equals(Object obj) { return (this == obj); }
方法需要传递一个对象。如果是以下三种情况那么就没有比较的必要,第一,传递的对象类型与该类不同可以直接返回false,第二,传递进来的对象为null值可以直接返回false,第三,传递进来的对象与该类对象一模一样直接返回true。最后则可以进行类的属性的判断,使用==进行值判断。这里要注意如果属性类型是String,String虽然是引用类型,但是String中存在常量池的概念,通过==比较的也是值。
@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; User other = (User) obj; if (username == null) { if (other.username != null) return false; } else if (!username.equals(other.username)) return false; return true; }
但是这个方法有小的漏洞,就是无法对方法的调用者进行空值校验,如果一个空值调用equals方法,会出现ClassCastException异常,表示代码尝试将对象转换为不属于实例的子类。这时候需要借助一个工具类Objects,该类从JDK1.7推出,拥有一系列静态的方法来操作对象。这里说的是它的equals方法
public static boolean equals(Object a, Object b) { return (a == b) || (a != null && a.equals(b)); }
||或运算符两边有一个满足则返回true,&&运算符若左边表达式为false则右边表达式不运行直接返回false,这样完美解决了空值调用equals方法出现ClassCastException的异常。