Java - 所有类的父类Object。
最近无聊整理一下Object类的方法,希望有所帮助。
Object类是一个特殊的类,是所有类的父类,如果一个类没有用extends明确指出继承于某个类,那么它默认继承Object类。
1.取得对象信息的方法:toString()
该方法在打印对象时被调用,将对象信息变为字符串返回,默认输出对象地址(hashcode 值),所以大多数情况下我们都会重写toString方法来得到对象的属性信息。
2.对象相等判断方法:equals()
该方法用于比较对象是否相等,大多数情况下要被重写来比较对象的内容是否相等,java的很多类比如String,Date就重写了此方法。
3.对象的存储地址值:hashcode()
hash算法,又被成为散列算法,基本上,哈希算法就是将对象本身的键值,通过特定的数学函数运算或者使用其他方法,转化成相应的数据存储地址的。
在常见的hash函数中有一种最简单的方法叫「除留余数法」,操作方法就是将要存入数据除以某个常数后,使用余数作为索引值。
例如:将323,458 ,25 ,340 ,28 ,969, 77 使用「除留余数法」存储在长度为11的数组中。我们假设上边说的某个常数即为数组长度11。每个数除以11后的余数即为该数在数组中的位置。则现在想要拿到77,只需要 访问arr[77%11] 就可以了。
在Java中 hashCode 的存在主要是用于提高容器查找和存储的快捷性,如 HashSet, Hashtable,HashMap 等,hashCode是用来在散列存储结构中确定对象的存储地址的。
当容器中数据很多时,通过hashCode可以快速查找数据(如上面所说的除留余数法),存储数据时也可快速查看要存储的数据是否已经存在(查重)。
要注意的是,重复的数据hashCode一定相等,但是hashCode相等的数据不一定相同。还以上面的除留余数法相同,,77除以11都余0,但是,除以11余0的不一定是77。碰撞的概率与具体的算法有关。而hashset在查重的时候则是先用hashcode来缩小寻找范围,最后还要用equals()来确定是否真的为相同的对象,所以重写equals一般都会重写hashcode方法来保证equals相同的情况下hashcode也相等
4.获得类型类:getClass()
Class class = this.getClass();涉及到了java中的反射
5.clone() throws CloneNotSupportedException
Java中要想自定义类的对象可以被复制,自定义类就必须实现Cloneable中的clone()方法
浅拷贝:
调用Object类中clone()方法产生的效果是:先在内存中开辟一块和原始对象一样的空间,然后原样拷贝原始对象中的内 容。对基本数据类型,这样的操作是没有问题的,但对非基本类型变量,我们知道它们保存的仅仅是对象的引用(引用指向堆内存中同一个对象),这也导致clone后的非基本类型变量和原始对象中相应的变量指向的是同一个对象。
深拷贝:
上面的例子要实现深拷贝需要完成两点:
a.非基本类型变量也要实现clone()
b.在clone方法里面要把非基本类型变量克隆后set到克隆对象里,例如下:
Class Person implements Cloneable{
private Animal pet;
@Override
public Object clone() throws CloneNotSupportedException {
Person clonePerson = (Person) super.clone();
clonePerson.pet = (Animal) pet.clone();
return clonePerson;
}
}
6.wait()
wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait()方法一直等待,直到获得锁或者被中断。wait(long timeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。
调用该方法后当前线程进入睡眠状态,直到以下事件发生。
(1)其他线程调用了该对象的notify方法。
(2)其他线程调用了该对象的notifyAll方法。
(3)其他线程调用了interrupt中断该线程。
(4)时间间隔到了。
7.notify()
该方法唤醒在该对象上等待的某个线程。
8.notifyAll()
该方法唤醒在该对象上等待的所有线程。
9.finalize()
该方法用于释放资源。因为无法确定该方法什么时候被调用,很少使用。Java允许在类中定义一个名为finalize()的方法。它的工作原理是:一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize()方法。并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。为什么不能显示直接调用finalize方法?如前文所述,finalize方法在垃圾回收时一定会被执行,而如果在此之前显示执行的话,也就是说finalize会被执行两次以上,而在第一次资源已经被释放,那么在第二次释放资源时系统一定会报错,因此一般finalize方法的访问权限和父类保持一致,为protected