equals方法是基类中一个方法,会默认继承,但只会对比两个对象的地址,往往需要重写以满足功能需要。
import java.util.Objects;
public class test {
public static void main(String[] args) {
People p1 = new People("shawn");
People p2 = new People("murphy");
System.out.println(p1.equals(p2));
}
}
class People{
private String name;
public People(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if(this.name == o.name){
return true;
}
}
return false;
}
}
代码会报错,因为Object类中并没有定义name变量,想要使用该变量就要向下强制转型,将整个equals方法修改为:
public boolean equals(Object o) {
if(o instanceof People){//老样子,向下强制转型之前做instanceof判断.
People p3 = (People)o;
if(this.name == p3.name){
return true;
}
}
return false;
}
但是,有这样一种情况,如果将p2定义为NULL,再传进equals方法中,虽然编译不会报错,但是这么写显然不合适.继续完善equals需要改进的地方:1.判断传进来的对象是否非空;2.判断传进来的对象和现有对象内存地址是否一致(如果堆内存都一致,证明本来就是同一个人).IDEA生成的equals方法源码如下:
public boolean equals(Object o) {
if (this == o) return true;//判断两个对象堆内存地址是否一致
if (o == null || getClass() != o.getClass()) return false;//判断是否非空或者是否(getClass方法暂时不了解)**TBD**
People people = (People) o;//向下强制类型转换.
return Objects.equals(name, people.name);
//return people.name==this.name;//这句是我自己写的,上面这个方法暂时不了解.
}
toString方法类似的,Object类中的toString方法一般也要重写.并且,String类的源码就重写了toString方法,how to prove that?
public class test {
public static void main(String[] args) {
String a = new String("wang");
System.out.println(a);//实际上是a.toString,系统会自动调用.and as we known,toString输出的对象堆存地址,实际上输出的确实""wang",证明String已经重写了该方法.
}
}
finalize方法
1.Object 类中源码:
protected void finalize() throws Throwable{ }
GC负责调用这个方法.
2.finalize方法只需要重写,不需要手动调用.当一个对象即将被销毁的时候(对象=null)垃圾回收器会自动调用该方法.
3.实际上就是为程序员提供的一个一个销毁对象时机,如果希望在销毁对象时做点什么,那么就写进finalize方法中.非常类似静态代码块,静态代码块在类加载时执行,并且只执行一次.
4.finalize方法并不是一有垃圾就启动,depends on 各种情况累加,由系统自动判断,只能人为地"建议"系统启动–“system.gc()”;,但并不一定.
5.该方法自JDK9开始被删除了.
hashCode方法
执行完之后返回经过哈希算法计算的值,该值实际上代表对象的地址.具体有待后续学习哈希算法后深入了解.TBD
clone方法
分为深克隆和浅克隆.TBD