资讯专栏INFORMATION COLUMN

Java 基础 | Object 源码解析

dendoink / 2836人阅读

摘要:注释指出方法返回散列值。直到其他线程调用此对象的方法或方法,当前线程被唤醒进入就绪状态。总超时时间以纳秒为单位计算为。以上注释主要就是描述了,和方法的使用规范。主要的区别在于在释放同时,释放了对象锁的控制。

Java 是一门面向对象的语言,在 Java 里面一切都可以看作是一个对象,而 Java 里面所有的对象都默认继承于 Object 类,所以狗哥今天就复习了一遍这个类。

上图看出 Object 一共有 12 个方法,其中 registerNatives() 是由 C 语言实现的,这个不在研究范围内。

1、getClass
/**
     * Returns the runtime class of this {@code Object}. The returned
     * {@code Class} object is the object that is locked by {@code
     * static synchronized} methods of the represented class.
*/
public final native Class getClass();

这个方法的作用就是返回某个对象的运行时类,它的返回值是 Class 类型,Class c = obj.getClass();通过对象 c ,我们可以获取该对象的所有成员方法,每个成员方法都是一个 Method 对象;我们也可以获取该对象的所有成员变量,每个成员变量都是一个 Field 对象;同样的,我们也可以获取该对象的构造函数,构造函数则是一个 Constructor 对象。这个方法在反射时会常用到。

2、hashCode
/**
     * Returns a hash code value for the object. This method is
     * supported for the benefit of hash tables such as those provided by
     * {@link java.util.HashMap}.
*/
    public native int hashCode();

这个方法的注释比较长,就不放出来了。注释指出:

hashCode 方法返回散列值。

返回值默认是由对象的地址转换而来的。

同一个对象调用 hashCode 的返回值是相等的。

两个对象的 equals 相等,那 hashCode 一定相等。

两个对象的 equals 不相等,那 hashCode 也不一定相等。

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

equals 的实现非常简单,它的作用就是比较两个对象是否相等,而比较的依据就是二者的内存地址。除此之外,equals 还遵循以下几个原则:

1、自反性:x.equals(x);  // true
2、对称性:x.equals(y) == y.equals(x);  // true
3、传递性:if (x.equals(y) && y.equals(z))
            x.equals(z); // true;

4、一致性,只要对象没有被修改,多次调用 equals() 方法结果不变:
x.equals(y) == x.equals(y); // true 

5、非空性,对任何不是 null 的对象 x 调用 x.equals(null) 结果都为 false :
x.equals(null); // false;

为什么要重写 hashcode 和 equals ?

这个问题之前分享过旧文:https://mp.weixin.qq.com/s/iI...

4、clone
protected native Object clone() throws CloneNotSupportedException;

clone() 是 Object 的 protected 方法,它不是 public,一个类不显式去重写 clone(),其它类就不能直接去调用该类实例的 clone() 方法。此外,Clone 的注释中还提到比较重要的几点:

克隆的对象必须要实现 Cloneable 接口并重写 clone 方法,否则会报 CloneNotSupportedException 异常

clone() 方法并不是 Cloneable 接口的方法,而是 Object 的一个 protected 方法。Cloneable 接口只是规定,如果一个类没有实现 Cloneable 接口又调用了 clone() 方法,就会抛出 CloneNotSupportedException。

浅拷贝:拷贝对象和原始对象的引用类型引用同一个对象。

深拷贝:拷贝对象和原始对象的引用类型引用不同对象。

关于浅拷贝与深拷贝的详解,请看这篇旧文:
https://mp.weixin.qq.com/s/I6...

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

这个方法应该没什么好讲的,原生的 toString 方法仅仅返回,对象名 + 它的 hashCode ,但做过开发的都知道,原生的 toString 作用不大。我们需要重写 toString 一般是因为方便调试,需要知道对象的属性值,而不仅仅是 hashCode 。所以,应该像下面这样重写:

public class Student {

    private int age;

    private String name;

    // 省略 get、set

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name="" + name + """ +
                "}";
    }
}
6、notify 和 wait
public final native void notify();
public final native void notifyAll();

首先是 notify ,注释就不贴出来了,notify 的作用就是随机唤醒在等待队列的某个线程,而 notifyAll 就是唤醒在等待队列的所有线程。

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 的作用是让当前线程进入等待状态,同时,wait() 也会让当前线程释放它所持有的锁。直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,当前线程被唤醒进入就绪状态。

wait(long timeout) (以毫秒为单位)让当前线程处于等待(阻塞)状态,直到其他线程调用此对象的notify() 方法或 notifyAll() 方法,或者超过指定的时间量,当前线程被唤醒进入就绪状态。

wait(long timeout, int nanos) 和 wait(long timeout) 功能一样,唯一的区别是这个可以提供更高的精度。总超时时间(以纳秒为单位)计算为 1000000 *timeout+ nanos。By the way ,wait(0,0) 和 wait(0) 效果一样。

除此之外,notify 和 wait 的注释中还有这么一段:

* 

* This method should only be called by a thread that is the owner * of this object"s monitor. A thread becomes the owner of the * object"s monitor in one of three ways: *

    *
  • By executing a synchronized instance method of that object. *
  • By executing the body of a {@code synchronized} statement * that synchronizes on the object. *
  • For objects of type {@code Class,} by executing a * synchronized static method of that class. *
*

看到这英文,刚过四级的我瑟瑟发抖。以上注释主要就是描述了,notify 和 wait 方法的使用规范。意思就是这二者必须在 synchronized 修饰的同步方法或同步代码中使用。

为什么 wait() 必须在同步 (Synchronized) 方法/代码块中调用?

答:调用 wait() 就是释放锁,释放锁的前提是必须要先获得锁,先获得锁才能释放锁。

为什么 notify()、notifyAll() 必须在同步 (Synchronized) 方法/代码块中调用?

答:notify()、notifyAll() 是将锁交给含有 wait() 方法的线程,让其继续执行下去,如果自身没有锁,怎么叫把锁交给其他线程呢?(本质是让处于入口队列的线程竞争锁)

详细解释请参考这篇博文:https://blog.csdn.net/qq_42145871/article/details/81950949

Thread.sleep() 和 Object.wait() 有什么区别?

首先,二者都可以暂停当前线程,释放 CPU 控制权。主要的区别在于 Object.wait()在释放 CPU 同时,释放了对象锁的控制。而 Thread.sleep() 没有对锁释放。换句话说 sleep 就是耍流氓,占着茅坑不拉屎。

推荐阅读:

1、java | 什么是动态代理

2、SpringBoot | 启动原理

3、SpringBoot | 自动配置原理

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/76021.html

相关文章

  • gson-plugin基础源码分析(二)

    摘要:对于如果以修改源码的方式,也可以通过判断当前的数据类型是否与预期的数据类型一致的方式进行。但由于每种数据类型都是一个匿名内部类,很难通过判断预期的数据类型是啥,所以可以通过添加捕获异常,在发生异常后,跳过解析。 一、项目地址 项目地址:github-gson-plugin 二、Gson解析核心类 1.ArrayTypeAdapter.JAVA 用于解析数组类型的数据 public ...

    beanlam 评论0 收藏0
  • Java集合之ArrayList源码解析

    摘要:数组的大小会根据容量的增长而动态的增长,具体的增长方式请看这里构造函数提供了三种方式的构造器。这些元素按照该的迭代器返回的顺序排列的。 原文地址 ArrayList ArrayList是List接口的 可变数组的实现。实现了所有可选列表操作,并允许包括 null 在内的所有元素。除了实现 List接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。ArrayList继承自 A...

    W4n9Hu1 评论0 收藏0
  • dubbo源码解析(四十二)序列化——开篇

    摘要:在版本中,支持五种序列化方式,分别是依赖阿里的库,功能强大支持普通类包括任意或完全兼容序列化协议的系列化框架,序列化速度大概是的倍,大小是大小的左右。但这里实际不是原生的序列化,而是阿里修改过的,它是默认启用的序列化方式自带的序列化实现。 序列化——开篇 目标:介绍dubbo中序列化的内容,对dubbo中支持的序列化方式做对比,介绍dubbo-serialization-api下的源码...

    keke 评论0 收藏0
  • 慕课网_《JSON快速入门(Java版)》学习总结

    摘要:时间年月日星期日说明本文部分内容均来自慕课网。慕课网教学示例源码无个人学习源码第一章课程概述课程介绍课程须知本课程面向所有使用语言进行开发的小伙伴。 时间:2017年05月21日星期日说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com教学示例源码:无个人学习源码:https://github.com/zccodere/s... 第一章:课程概述 1-1 ...

    shiina 评论0 收藏0

发表评论

0条评论

dendoink

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<