所有的Java对象都隐式地继承了Object对象,也就是说所有的Java对象都拥有Object默认的方法。
object有什么方法呢?
equals和hashCode方法
首先hansCode在Object中的实现为:
这个方法返回对象的散列码,一般如果这两个对象相等(相当于两个对象通过equals调用之后返回true),那么这两个类的hashCode方法返回的散列码是一样的。但是有时散列码一样,对象不一定相等。所以编写散列码计算时,公式尽量是不同类其散列码也不一样,即一个类,在hashCode里面返回唯一的一个hash值。
散列码重写例子:
equals在Object中的实现为
Object中的equals方法主要用于判断对象的内存地址引用是不是同一个地址(是不是同一个对象),即比较对象的地址。但是我们一般都是通过对象内容来进行判断。所以一般都需要重写equals方法。注意:重写了equals方法,就一定要重写hashCode方法。
equals重写例子:
String类实现的equals方法和hashCode方法
我们平时判断两个字符串是否相等时,就直接使用String.equals("")。是因为String类已经实现了equals和hashCode方法了。
String类实现equals和hashCode的代码:
- 如果两个对象的地址相同,那么equals返回true;
- 如果两个对象类型不同,返回false;
- 类型相同,先强制转换类型,先比较字符串长度,再注意比较
- 利用公式h=31*h+value[i]来生成哈希值
toString方法:主要用来标志对象的,以文本的方式来表示一个对象。
toString在Object中的实现:
当我们输出一个对象时,就直接是:
我们使用toString时,一般都是为了输出我们想要知道的对象的信息。所以这时我们需要重写toString方法。
集合的toString方法:
clone方法
创建对象方式:
浅拷贝和深拷贝对比:
浅拷贝:只拷贝了对象,成员变量还是引用之前的
深拷贝:也拷贝了成员变量
最后需要克隆的对象要实现Cloneable接口和重写clone方法。
wait和notify方法
看完上面的注释我们可以总结以下的要点:
无论是wait、notify还是notifyAll()都需要由监听器对象(锁对象)来进行调用
简单来说:他们都是在同步代码块中调用的,否则会抛出异常!
notify()唤醒的是在等待队列的某个线程(不确定会唤醒哪个),
notifyAll()
唤醒的是等待队列所有线程
导致wait()的线程被唤醒可以有4种情况
该线程被中断
wait()
时间到了被
notify()
唤醒被
notifyAll()
唤醒
调用
wait()
的线程会释放掉锁
为什么wait和notify方法是在Object方法上?
wait()
和notify()
是Java给我们提供线程之间通信的API
因为我们的锁是对象锁每个对象都可以成为锁。让当前线程等待某个对象的锁,当然应该通过这个对象来操作了。
锁对象是任意的,所以这些方法必须定义在Object类中。
notify会唤醒某个处于等待队列的线程,但是notify方法调用后,被唤醒的线程不会立马获得到锁对象。而是等notify的synchronize代码块执行完后才会获得锁对象。
sleep和wait的区别:
两者都是暂停当前线程,释放cpu控制权。
但是:wait在释放cpu时,还释放了锁对象。而sleep没有释放锁对象。
finalize()方法
垃圾回收器准备释放内存的时候,会先调用finalize()。