Object类
是类层次结构的根。 每个类都有Object
作为超类。 所有对象(包括数组)都实现了这个类的方法。
源码:
package java.lang;
public class Object {
/**
* 说明:
* registerNatives函数前面有native关键字修饰,Java中,
* 用native关键字修饰的函数表明该方法的实现并不是在Java中去完成,
* 而是由C/C++去完成,并被编译成了.dll,由Java去调用。方法的具体实现体在dll文件中,
* 对于不同平台,其具体实现应该有所不同。用native修饰,即表示操作系统,需要提供此方法,
* Java本身需要使用。具体到registerNatives()方法本身,
* 其主要作用是将C/C++中的方法映射到Java中的native方法,实现方法命名的解耦。
*/
private static native void registerNatives();
//静态代码块
static {
registerNatives();
}
/**
* 说明:
* 返回object运行时的类
* @return
*/
public final native Class<?> getClass();
/**
* 说明:
* 返回对象的哈希值、通过哈希(散列)函数得到
*
* 常见Hash函数有以下几个:
* 1、直接定址法:直接以关键字k或者k加上某个常数(k+c)作为哈希地址。
* 2、数字分析法:提取关键字中取值比较均匀的数字作为哈希地址。
* 3、除留余数法:用关键字k除以某个不大于哈希表长度m的数p,将所得余数作为哈希表地址。
* 4、分段叠加法:按照哈希表地址位数将关键字分成位数相等的几部分,
* 其中最后一部分可以比较短。然后将这几部分相加,舍弃最高进位后的结果就是该关键字的哈希地址。
* 5、平方取中法:如果关键字各个部分分布都不均匀的话,可以先求出它的平方值,然后按照需求取中间的几位作为哈希地址。
* 6、伪随机数法:采用一个伪随机数当作哈希函数。
*
* 常见的解决碰撞的方法:
*1、开放定址法:开放定址法就是一旦发生了冲突,就去寻找下一个空的散列地址,
* 只要散列表足够大,空的散列地址总能找到,并将记录存入。
* 2、链地址法:将哈希表的每个单元作为链表的头结点,所有哈希地址为i的元素构成一个同义词链表。
* 即发生冲突时就把该关键字链在以该单元为头结点的链表的尾部。
* 3、再哈希法:当哈希地址发生冲突用其他的函数计算另一个哈希函数地址,直到冲突不再产生为止。
* 4、建立公共溢出区:将哈希表分为基本表和溢出表两部分,发生冲突的元素都放入溢出表中。
* @return
*/
public native int hashCode();
/**
* 说明:
* 用来比较方法两个对象的内容是否相等。不能用于基本数据比较
* 区别:
* ==:如果比较的对象是基本数据类型,则比较的是数值是否相等;如果比较的是引用数据类型,
* 则比较的是对象的地址值是否相等。
* @param obj
* @return
*/
public boolean equals(Object obj) {
return (this == obj);
}
/**
* 说明:
* 创建并返回此对象的副本。重新在堆里创建一个对象、栈内地址也不一样。
* 浅拷贝:如果两个Person 对象的name 的地址值相同, 说明两个对象的name 都指向同一个String 对象
* 深拷贝:而如果两个Person对象的name 的地址值不同, 那么就说明指向不同的String 对象,
* @return
* @throws CloneNotSupportedException
*/
protected native Object clone() throws CloneNotSupportedException;
/**
* 说明:
* 返回对象的字符串表示形式
*Integer.toHexString()//返回字符串表示的16进制数(无符号)
* @return
*/
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
/**
* 说明:
* 唤醒正在等待对象监视器的单个线程。
*/
public final native void notify();
/**
* 说明:
* 唤醒正在等待对象监视器的所有线程。
*/
public final native void notifyAll();
/**
* 说明:
* 调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待池中,
(进入等待队列,也就是阻塞的一种,叫等待阻塞)同时释放对象锁,并让出CPU资源
* 传入参数就是在参数结束的时间后开始等待,不穿如参数就是直接等待。
* wait()使用notify()方法、notiftAll()方法或者等待指定时间来唤醒当前等待池中的线程。
等待的线程只是被激活,
* 但是必须得再次获得锁才能继续往下执行,也就是说只要锁没被释放,
原等待线程因为为获取锁仍然无法继续执行。
* notify的作用只负责唤醒线程,线程被唤醒后有权利重新参与线程的调度。
*区别:sleep()
* sleep()方法是线程类(Thread)的静态方法,让调用的线程进入指定时间睡眠状态,
使得当前线程进入阻塞状态,
* 告诉系统至少在指定时间内不需要为线程调度器为该线程分配执行时间片,给执行机会给其他线程
* (实际上,调用sleep()方法时并不要求持有任何锁,即sleep()可在任何地方使用。),
但是监控状态依然保持,到时后会自动恢复。
*
* @param timeout
* @throws InterruptedException
* 如果抛出 InterruptedException 意味着一个方法是阻塞方法
* IllegalArgumentException - 如果超时值是负数,或者毫微秒值不在 0-999999 范围内。
* IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。
* InterruptedException - 如果在当前线程等待通知之前或者正在等待通知时,任何线程中断了当前线程。在抛出此异常时,当前线程的 中断状态 被清除。(中断异常)
*
* wait(0, 0) 与 wait(0) 相同
*/
public final native void wait(long timeout) throws InterruptedException;
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos > 0) {
timeout++;
}
wait(timeout);
}
public final void wait() throws InterruptedException {
wait(0);
}
/**
* 说明:
* Object 类的一个方法,在垃圾回收器执行的时候会调用被回收对象的此方法,可以覆盖此方法
* 提供垃圾收集时的其他资源回收、这是一个被动的方法(其实就是回调方法),不需要我们调用。
* @throws Throwable
*/
protected void finalize() throws Throwable { }
}
总结:常用方法
getClass:获得运行时类
hashCode:获取hash值
equals:比较对象内容是否相等
wait:放弃锁、阻塞等待
notify:唤醒线程
notifyAll:唤醒全部线程