我们都知道,Java中所有的类都继承自java.lang.Object。
也就是说这个类中的方法是类库作者认为所有类都应该具有的方法,那么它的重要性就不言而喻了,现在我们一起来对这个类进行一下简单的分析。
首先来看一下源码(基于JDK 1.8.0_45)
package java.lang;
/*
* @since JDK1.0
*/
public class Object {
private static native void registerNatives();
static {
registerNatives();
}
public final native Class<?> getClass();
public native int hashCode();
public boolean equals(Object obj) {
return (this == obj);
}
protected native Object clone() throws CloneNotSupportedException;
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
public final native void notify();
public final native void notifyAll();
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 >= 500000 || (nanos != 0 && timeout == 0)) {
timeout++;
}
wait(timeout);
}
public final void wait() throws InterruptedException {
wait(0);
}
protected void finalize() throws Throwable { }
}
下面对每个方法进行详细说明:
//通过JNI调用本地C/C++代码,注册本地方法
private static native void registerNatives();
//静态代码块,JVM加载类时执行,仅执行一次
static {
registerNatives();
}
这个静态代码块会在JVM加载类时执行,且只会被执行一次。它保证了实例化Object对象或其子类(Object拥有默认构造方法)时一定会执行registerNatives()方法。
而registerNatives()方法主要作用是将C/C++中的方法映射到Java中,实现方法命名的解耦。
备注:若一个方法由native关键字修饰,则表明该方法的实现并不是在Java中去完成,而是由C/C++去完成,并被编译成了.dll,由Java去调用。方法的具体实现体在dll文件中,对于不同平台,其具体实现有所不同。
//返回此 Object 的运行时类。
public final native Class<?> getClass();
getClass()也是一个native方法,返回的是此Object对象的类对象/运行时类对象Class
//返回该对象的哈希码值。
public native int hashCode();
hashCode()方法应该返回一个整形数值,表示该对象的哈希码值。
此方法也被native关键字修饰,因此其默认实现与JVM具体实现有关。
这个方法返回的哈希码值主要作用在于增强Java集合框架中哈希表(如:HashMap,Hashtable等)的性能。
关于hashCode()方法的通用约定:
1.在一个Java应用程序程序执行期间,对于同一对象多次调用hashCode()方法时,其返回的哈希码是相同的(前提是将对象进行equals比较时所用的标尺信息未做修改);
2.如果两个对象相等(依据:调用equals()方法),那么这两个对象调用hashCode()返回的哈希码也必须相等;
3.两个对象调用hasCode()返回的哈希码相等,这两个对象不一定相等。
//指示其他某个对象是否与此对象“相等”。
public boolean equals(Object obj) {
return (this == obj);
}
equals()方法的语义:判断两个对象是否相等。
返回值:true表示两个对象相等,false表示两个对象不相等
默认实现是直接比较两个对象的地址值,各个Object的实现类可根据自己的语义来重写此方法。例如:String类重写了此方法表示当两个String对象地址相同或者封装的char数组长度相等且每一位都相同时,可认为这两个String对象相等。
//创建并返回此对象的一个副本。
protected native Object clone() throws CloneNotSupportedException;
clone()方法与对象的克隆有关,当某个Object的实现类实现了Cloneable这个标记接口时,才有作用。
返回值:返回此对象的一个副本(注意浅克隆与深克隆的区别!)
使用native关键字修饰,说明此方法也不是在Java中实现的。
//返回该对象的字符串表示。
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
toString()方法返回该对象的字符串表示。
默认返回值分析:
getClass()方法得到类对象,getClassName()方法以String形式返回类对象的名称(含包名)。Integer.toHexString(hashCode())则是以对象的哈希码为实参,返回它的16进制无符号整数形式对应的字符串。
因此可以说,toString()的默认实现返回的字符串由对象的类型和其哈希码唯一确定。
一般都会重写此方法,使之返回更加有意义的字符串。
//GC在回收此对象前调用此方法。
protected void finalize() throws Throwable { }
finalize()方法与对象的回收有关,GC在回收此对象前调用此方法。
一般用来完成一些对象销毁的必要动作,然而由于JVM实现的不同,导致GC在回收对象时不一定会调用此方法。因此不要太依赖此方法,能不用就不用。
//唤醒在此对象监视器上等待的单个线程。
public final native void notify();
//唤醒在此对象监视器上等待的所有线程。
public final native void notifyAll();
notify()方法与synchronized关键字配合使用,与Java多线程有关。
在本对象被作为对象监视器且当前线程持有对象锁时,可使用此方法唤醒在这个对象监视器上等待的其它线程,当前线程不立即释放锁,而是与被唤醒的线程公平竞争。
//在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。
//本地方法调用
public final native void wait(long timeout) throws InterruptedException;
// 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。
//参数:timeout--毫秒
// nanos--毫微秒
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 >= 500000 || (nanos != 0 && timeout == 0)) {
timeout++;
}
wait(timeout);
}
//在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
public final void wait() throws InterruptedException {
//相当于永远休眠
wait(0);
}
wait()方法与synchronized关键字配合使用,与Java多线程有关。
在本对象被作为对象监视器且当前线程持有对象锁时,可使用此方法使当前线程进入等待/休眠状态,直到满足条件时才被唤醒。在此期间当前线程不持有锁。
大致就是这样啦,本人水平有限,难免有错误,如果您看出哪里有问题,请指出!