Java基础-Object类解析

在学过Java的面向对象后,我们都知道“万物皆对象”,Object是所有类的基类,所有类显式或隐式地继承于Object。

下面是Java对Object类的描述:

package java.lang;

/**
 * Class {@code Object} is the root of the class hierarchy.
 * Every class has {@code Object} as a superclass. All objects,
 * including arrays, implement the methods of this class.
 *
 * @author  unascribed
 * @see     java.lang.Class
 * @since   JDK1.0
 */
public class Object {
    ...
}

Object方法

image-20210216134654167

其中,一个private static方法、两个protected方法、9个public方法,而且还存在很多native方法。

registerNatives()

private static native void registerNatives();
static {
    registerNatives();
}

该方法是私有的静态本地方法,在类加载的时候被执行。

作用:对Object类中使用到的几个native方法进行注册。

getClass()

public final native Class<?> getClass();

该方法是一个本地方法,返回一个Class对象,而且不可以被重写。

作用:获取定义当类实例的Class对象。

常用于反射机制中,可以获取类的相关信息。

hashCode()

public native int hashCode();

该方法是一个本地方法,返回一个int值,但可以被重写。

作用:获取当前实例的散列码。该hashCode用来标识对象。

常用于集合框架中对象元素的比较。集合框架中,比如set,map在添加元素时,都是获取hashCode再根据定义的算法来生成hash值,从而来确定添加元素在集合数据结构中的存储位置。

注意:该hashCode不是对象地址

地址:变量在内存中存储位置

hashCode:根据一定散列算法为对象生成的标识码

通过该方法的注释可以知道,各个JVM厂商必须遵循一定的契约(contract):

  • 多次调用同一个对象的HashCode()必须返回同一个整数
  • 如果两个对象的equals比较返回true,要求它们的hashCode方法也必须返回同一个整数
  • 如果两个对象的equals比较返回false,并不要求它们的hashCode方法下相同的整数

当然,因为该方法可以被重写,所以对象的hashCode可以让我们自己指定,但生成hashCode必须满足以上的要求。

equals(Object obj)

public boolean equals(Object obj) {
    return (this == obj);
}

该方法返回一个boolean值,可以被重写。

作用:用来比较两个对象是否相等。

对象的相等比较涉及两种方式:

  • ==运算符:比较引用地址
  • equals方法:比较对象内容

从源码可以看到:

equals方法是默认比较两个对象的地址是否相等。

默认情况下,无法比较两个对象的内容是否一致。

所以,当我们需要比较不同实例对象的内容是否相等时就需要重写该类的equals方法,所指的内容也就是某些属性值。

重写equals方法需要满足一下条件(x,y,z都是相同类的实例对象,且不为空):

  • 自反性:必须有x.equals(x)返回true
  • 对称性:如果x.equals(y)返回true,则y.equals(x)也要返回true
  • 传递性:如果x.equals(y)返回true,且y.equals(z)返回true,则x.equals(z)也要返回true
  • 一致性:相同的两个对象,相同的调用方式,多次调用equals方法必须返回相同的值
  • 非空性:x.equals(null)永远返回false

例:

@Override
public boolean equals(Object obj) {
    // 相同类实例、非空
    if(!(obj instanceof Student)) {
        return false;
    }
    Student stuObj = (Student) obj;
    // 比较对象地址
    if (this == stuObj) {
        return true;
    }
    // 比较对象内容
    if (stuObj.name.equals(this.name) && stuObj.sex.equals(this.sex) && stuObj.age.equals(this.age)) {
        return true;
    } else {
        return false;
    }
}

clone()

protected native Object clone() throws CloneNotSupportedException;

该方法是一个被保护的本地方法,可以被重写。

作用:将当前对象的实例复制一份,生成一个新的对象实例。

注意:只有实现了Cloneable接口的类才能调用clone方法,否则会抛出CloneNotSupportedException。

从方法注释我们可以知道:

  • x.clone() != x返回true
  • x.clone().getClass() == x.getClass()返回true,不必须
  • x.clone().equals(x)返回true,不必须

对象的拷贝类型:

  • 浅拷贝

  • 深拷贝

区别:对象中的引用类型属性的引用是否改变。

其本质是:引用类型的属性对象是否重新开辟空间创建。

实现深拷贝:需要将每一层的引用对象都实现Cloneable对象。

toString()

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

作用:返回一个实例对象的字符串表现形式。

具体形式是该实例的类名加上“@”再加上该实例的hashCode的十六进制。一般为了查看到详细的实例信息,都会重新该方法。

wait()

public final void wait() throws InterruptedException {
    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);
}

该方法用于线程通信。

作用:wait及其重载方法(设置等待时间)是让当前线程进入等待状态(会释放锁资源),直到当前线程被唤醒或者等待超时,再次进入就绪状态。

注意:调用wait方法的当前线程必须持有对象监视器(锁资源),否则会抛出IllegalMonitorStateException

调用wait方法的当前线程会立即释放持有的对象监视器,从而让其他线程有机会获取该对象监视器。

notify()

public final native void notify();
public final native void notifyAll();

该方法用于线程通信。

作用:notify和notifyAll都是为了唤醒相同对象监视器上处于等待状态的线程。

不同:

  • notify:当前线程随机唤醒一个相同对象监视器上的等待线程
  • notifyAll:当前线程唤醒相同对象监视器上的所有等待线程

源码注释描述:

Wakes up a single thread that is waiting on this object's
monitor. If any threads are waiting on this object, one of them
is chosen to be awakened. The choice is arbitrary and occurs at
the discretion of the implementation. A thread waits on an object's
monitor by calling one of the {@code wait} methods.

注意:调用notify方法的当前线程必须持有对象监视器,否则会抛出IllegalMonitorStateException

当前线程调用notify方法,会将因为争夺相同对象监视器的其他线程唤醒。但是其他线程不会立即获取到对象监视器,因为当前线程还未释放对象监视器(没有执行完同步代码块)。

finalize()

protected void finalize() throws Throwable { }

该方法只有空方法体,可以重写,但是不建议重写。

作用:通常用于进行一些资源释放。

特点:

  • 在对象被垃圾回收时被JVM调用。
  • 该方法体中抛出的异常会被JVM catch并忽略。
  • 任何对象的finalize方法最多只会被调用一次,并不能保证一定会被调用。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容