Java Object类初探

我们都知道,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多线程有关。
在本对象被作为对象监视器且当前线程持有对象锁时,可使用此方法使当前线程进入等待/休眠状态,直到满足条件时才被唤醒。在此期间当前线程不持有锁。

大致就是这样啦,本人水平有限,难免有错误,如果您看出哪里有问题,请指出!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值