Object类详解

Java Object 类是所有类的父类,也就是说 Java 的所有类都继承了 Object,子类可以使用 Object 的所有方法。由于所有的类都继承在Object类,因此省略了extends Object关键字。
注意,严格意义上来说,基本数据类型并不继承自Object。这主要是出于性能方面的考虑。(换言之,对bool、int、double等数据类型使用基本类型,其目的是为了提高性能)

单继承与多继承

单继承和多继承的差异体现在是否支持多个父类。对于单继承来说,其父类只能有一个,对于多继承来说,其父类可以由多个。
相比多继承,单继承模式更加简单,其类结构更加清晰。单继承语言有Java、C#等,多继承语言有C++等。
对于Java等单继承语言,如果需要使用多继承特性,可以通过“组合”的方式,间接实现多继承。

Object源码分析

Object 类位于 java.lang 包中,其源码定义如下:

public class Object {
    /**
     * 返回运行时类型信息
     */
    public final native Class<?> getClass();
    /**
     * 返回对象的hashcode值,主要用于需要hash table
     */
    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();
    /**
     * 使当前线程等待,直到被唤醒或指定的时间(timeout参数,单位毫秒)已经过去。
     * 当timeout为0时,当前线程将一直等待,直到被唤醒
     */
    public final native void wait(long timeout) throws InterruptedException;
    /**
      * 这个方法与一个参数的wait方法作用一致,
      * 只是这个方法,允许更好地控制时间。
      *(分析源码,其仍没有实现微秒粒度)
      */
    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);
    }
    /**
     * 释放资源
     */
    protected void finalize() throws Throwable { }
}

clone方法

clone方法是一个保护方法,用于实现对象的浅复制。注意,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。

浅拷贝与深拷贝(Shallow Clone与Deep Clone)

也称浅复制与深复制、浅克隆与深克隆等。这里统一使用浅拷贝与深拷贝。
所谓的浅拷贝,对于基本数据类型复制其值,对于对象类型复制其引用。所谓的深拷贝,无论是基本数据类型,还是对象类型,都是复制其值。所以,对于浅拷贝来说,如果待复制数据包含对象变量,则针对该对象变量的修改会同时影响待复制对象和已生成对象。对于深拷贝来说,待复制数据和已生成数据完全隔离,两者互不影响。

getClass方法

getClass方法是一个final方法,该方法将返回表示该对象的实际类型的Class引用。getClass方法主要用在反射场景。

toString方法

toString方法用于返回对象的字符串表示,该方法用得比较多(如获取对象的序列化表示),一般子类都有覆盖。

equals方法和hashCode方法

Object类中定义equals方法,其初始行为是比较对象的内存地址。在实际应用中,经常重写equals方法。在重写equals方法时,一定要重写hashCode方法。
这是因为,在哈希表容器(如Hashtable、HashMap等)时,会先比较哈希码,只有在哈希码相等的情况下,才会进一步equals方法判断是否相等(这主要考虑equals方法带来的性能问题)。

wait方法和notify方法和notifyAll方法

wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait()方法一直等待,直到获得锁或者被中断。wait(long timeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。调用该方法后当前线程进入睡眠状态,直到以下事件发生:
(1)其他线程调用了该对象的notify方法或notifyAll方法;
(2)其他线程调用了interrupt中断该线程;
(3)时间间隔到了。
此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常。
notify方法可以唤醒在该对象上等待的某个线程,而notifyAll方法则可以唤醒在该对象上等待的所有线程。

finalize方法

该方法用于释放资源。在GC准备释放对象所占用的内存空间之前,它将首先调用finalize()方法。
不推荐使用finalize方法或重写finalize方法
这主要是因为,在Java中,GC主要是自动回收,因而并不能保证finalize方法会被及时地执行(垃圾对象的回收时机具有不确定性),也不能保证它们会被执行(假设程序由始至终都未触发垃圾回收)。
由于finalize()方法的调用时机具有不确定性,从一个对象变得不可到达开始,到finalize()方法被执行,所花费的时间这段时间是任意长的,所以不能依赖finalize()方法能及时的回收占用的资源。
如果在资源耗尽之前,GC却仍未触发,则finalize()方法将不会被执行。针对这种场景,通常的做法是提供显示的close()方法供客户端手动调用。
另外,重写finalize()方法意味着延长了回收对象时需要进行更多的操作,从而延长了对象回收的时间。

参考

https://www.apiref.com/java11-zh/java.base/java/lang/Object.html Class Object
https://www.runoob.com/java/java-object-class.html Java Object 类
https://blog.csdn.net/CrazyLai1996/article/details/84900818 Java中finalize()方法的使用
https://www.cnblogs.com/zhangyinhua/p/7715486.html Java常用类(一)之Object类详解

你可能感兴趣的:(#,Java基础,Java,#,Java类型系统,java,object,Object,根类)