`

Object类 源码分析

    博客分类:
  • java
阅读更多
首先看看方法:

public final native Class<?> getClass();
public native int hashCode();
public boolean equals(Object obj);
protected native Object clone() throws CloneNotSupportedException;
public String toString();
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;
public final void wait() throws InterruptedException;
protected void finalize() throws Throwable;


1. getClass方法

这是一个native方法,返回的是当前对象的类的字节码。

2. hashCode方法

这是一个native方法,返回的是根据当前对象的物理地址生成的哈希码,目的是为了区分不同的对象,这在一些根据Hash值来存储的集合中很有用。

如果两个对象经过equals比较后,返回true,那么它们的hashCode也必须是相同的;
如果两个对象经过equals比较后,返回false,那么它们的hashCode可以不同,也可以相同。

3. equals方法

比较当前对象是否和某个object相等。如果重写这个方法,需要满足下面的契约:
a. reflexive (反身性)
   => x != null
   x.equals(x) return true

b. symmetric (对称性)
   => x != null && y != null
   if (x.equals(y)) y.equals(x) return true

c. transitive (传递性)
   => x != null && y != null && z != null
   if (x.equals(y) && y.equals(z)) x.equals(z) return true

d. consistent (连贯性)
   => x != null && y != null
   x.equals(y) return false;
   ...
   x.equals(y) return false;

e. x != null
   x.equals(null) return false

4. clone方法

这是一个native方法,创建并返回该对象的拷贝。

对于某个对象x,
x.clone() != x return true // 但这不是绝对的
x.clone().getClass() == x.getClass() return true // 但这不是绝对的

典型情况下:
x.clone().equals(x) return true // 但这不是绝对的

按照惯例,该方法调用suer.clone()。如果这个类和所有它的超类都遵循这个规则,那么:x.clone().getClass() == x.getClass()

按照惯例,拷贝的对象应该和该对象相互独立。为了达到这个目标,在返回之前需要对其中的一个或几个字段进行修改,拷贝组成当前对象的变化部分,然后把引用改成指向拷贝。如果一个类只有原始类型字段或者对不变对象的引用,不需要做这些修改。

过程:
a. 首先如果当前对象的类没有实现Cloneable接口,抛CloneNotSupportedException异常
b. 创建当前对象的类的新实例,用当前对象的内容来初始化所有的字段。所以只是复制了引用,是shallow copy

5. toString方法

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

返回该对象的string表示形式。该表示应该能够表达该对象的信息。最好是所有的子类都重写该方法。

Object的toString方法返回:该对象的类名 + "@" + 该对象hashCode的16进制表示形式

6. notify方法

这是一个native方法,唤醒一个在当前对象监视器上等待的线程。

被唤醒的线程直到当前线程释放锁后才可以执行,并且和其它线程竞争对象的拥有权(没有优先级之分)。

这个方法应该仅仅被拥有对象监视器的线程所调用。

一个线程成为对象的监视器的拥有者的三种方法:
a. 执行该对象上的一个同步(synchronized)方法
b. 执行一个同步在该对象上的代码块
c. 执行该对象的类上的静态同步方法

7. notifyAll方法

这是一个native方法,唤醒所有在当前对象监视器上等待的线程。

和notify类似。

8. wait(long timeout)方法

这是一个native方法,使当前线程等待,直到另外一个线程调用改对象的notify或notifyAll方法,或者等待时间已到。

当前线程必须拥有该对象的监视器。

该方法会让当前线程T进入到当前对象的等待集中,让出当前对象的监视器,T被禁用直到下面情况中的一种发生:
a. 其它线程调用当前对象的notify方法,并且T恰好被选中唤醒
b. 其它线程调用当前对象的notifyAll方法
c. 其它线程暂停T
d. 等待时间已到

被唤醒后,T从等待集中被移除和启用等待线程调度,接着会和其它线程竞争当前对象的拥有权。如果T成功了,就会从wait方法的调用处返回,当前对象和T的同步状态和调用wait时一样。

有种情况是伪唤醒,就是T从wait处返回了,没有出现上面说的4种情况。所以wait方法放在loop块中,确保不是伪唤醒:

synchronized (obj) {
	while (<condition does not hold>)
		obj.wait(timeout);
	... // Perform action appropriate to condition
}

如果在wait之前或wait的时候,当前线程被中断了,那么直到当前线程恢复时才会抛InterruptedException。

wait方法会使当前线程让出当前对象的拥有权,但是不会让出同步的其它对象。

该方法必须是在当前线程是当前对象的拥有时才可以调用。

9. wait(long timeout, int 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);
    }

看到该方法的签名,以为nanos会提供更高精度的控制。但是代码将nanos四舍五入到timeout,调用wait(timeout)方法。

10. wait()方法

    public final void wait() throws InterruptedException {
        wait(0);
    }

这里的参数0表示没有时间限制。

11. finalize方法

垃圾回收器觉得该对象没有被其它任何存在的线程引用时会调用该方法。子类可以通过复写该方法来达到资源释放。

Java不能保证什么线程会来调用某个对象的finalize方法。可以保证的是,当finalize被调用时,调用finalize的线程不会拥有用户可见的同步锁。在方法调用过程中出现的异常会被忽略并且方法调用会终止。

任何对象的finalize方法只会被调用一次。
分享到:
评论

相关推荐

    qt object类分析

    qt最重要的类, object类的源码分析,相当实用, 相当有参考价值

    FreeCAD源码分析:数据显示流程(试用版)

    讲述Open Inventor (OIV)的编程要点、基本概念...分析FreeCAD中几何渲染相关的DocumentObject、ViewProvider、View3DInventorViewer、View3DInventor等类,通过Part模块中Cube的创建过程,梳理了几何数据显示的流程。

    redis键值数据库源码分析

    主要通过redisObject进行类型转换。 t_list.c list在Server/Client中的应答操作。主要通过redisObject进行类型转换。 t_set.c set在Server/Client中的应答操作。主要通过redisObject进行类型转换。 t_string.c ...

    Android 动画机制 补间、属性、帧动画、源码分析

    Android 动画机制 补间、属性、帧动画、源码分析 Android系统提供了很多丰富的API去实现UI的2D与3D动画,最主要的划分可以分为如下几类: * View Animation:最早提供的一种动画,用来这只view。 * Drawable ...

    Object-XML文件的相互转换分析

    NULL 博文链接:https://wang-yanli.iteye.com/blog/1477681

    java8集合源码分析-JUC:高并发与多线程

    集合源码分析 高并发与多线程 Stargazers over time 线程 线程的创建和启动 线程的sleep、yield、join 线程的状态 代码在 部分。 synchronized关键字(悲观锁) synchronized(Object) 不能用String常量、Integer、Long...

    Java从JDK源码角度对Object进行实例分析

    主要介绍了Java从JDK源码角度对Object进行实例分析,具有一定借鉴价值,需要的朋友可以参考下。

    object-assign:Object.assign() 实现

    ES6 Object.assign() 的实现; 安装 $ bower 安装 es6-object-assign 用法 var oa = new ObjectAssign ( ) ; var t = { name : "lisa" , age : 25 } ; var r = { speak : function ( ) { console . log ( 'Hello, ...

    java8集合源码分析-Java-Virtual-Machine:Java虚拟机资源汇总

    集合源码分析 Java-Virtual-Machine Java虚拟机资源汇总 最后更新时间 2019-10-24 注意 资料的排列的顺序不分先后。 资料的所有权归原作者所有,这里是汇总。 知识水平的限制,导致资料的介绍或者范围有一定的局限性...

    Retrofit 源码分析初探

    介绍源码前,我们先看下Retrofit的基本使用,大致了解下流程,跟着这个流程来分析源码才不会乱。 1、初始化Retrofit对象 Retrofit retrofit = new Retrofit.Builder() //使用自定义的mGsonConverterFactory ....

    源码分析专题之Mybatis课程一之实用篇.pdf

    ORM是Object和Relation之间的映射,包括Object-&gt;Relation和Relation-&gt;Object两方面。Hibernate是个完整的ORM框架,而MyBatis完成的是Relation-&gt;Object,也就是其所说的data mapper framework。关于ORM的一些设计思路...

    uml对象设计与编程objectdesign

    这是关于UML分析方面的,如何将UML分析与具体的对象设计结合在一起

    基于jdk1.8 的ArrayList的源码分析

    基于jdk1.8 的ArrayList的源码分析 前言:一说到ArrayList的大家可能立马想到的就是:有序、可重复、查找快但是增删慢、线程不安全。但是具体的原因都不是很清楚,本文就会根据这些问题和大家一起去学习。主要会从...

    java8集合源码分析-Java-Virtual-Machine:Java-虚拟机

    集合源码分析 Java-Virtual-Machine Java虚拟机资源汇总 最后更新时间 2019-04-23 注意 资料的排列的顺序不分先后。 资料的所有权归原作者所有,这里是汇总。 知识水平的限制,导致资料的介绍或者范围有一定的局限性...

    STL源码剖析

    这本书也不适合带领你学习面向对象(Object Oriented)技术 — 是的,STL 与面向对象没有太多关连。本书前言清楚说明了书籍的定位和合适的读者,以及各类基础读物。如果你的Generic Programming/STL实力足以阅读本书...

    源码学习与分析.zip

    如何知道数据变了,其实上文我们已经给出答案了,就是通过Object.defineProperty( )对属性设置一个set函数,当数据改变了就会来触发这个函数,所以我们只要将一些需要更新的方法放在这里面就可以实现data更新view了...

    java8集合源码分析-javaInterview:java面试

    集合源码分析 2020年深圳java打工仔找工作记录帖,有一段时间的社畜了,所以直奔主题, 找的资料都是面试常用的,整理一下,希望能帮到大家 主要三个部分 1.搜集面试题目 2.java资料 3 找工作日期记录,看从准备工作开始,...

    Sensor-Fusion-3D-Object-Tracking:该项目是Udacity的Sensor Fusion Nanodegree中的第三个项目。 该项目涵盖了以下TTC构件中显示的所有部分

    SFND 3D对象跟踪 该项目是Udacity的Sensor Fusion Nanodegree中的第三个项目。 该项目涵盖了TTC构件下面显示的所有部分。本地运行的依赖项cmake&gt; = 2.8 所有操作系统:make&gt; = 4.1(Linux,Mac),3.81(Windows) ...

    Collections源码java-jdk1.8-source-analysis:Java8源码分析,J.U.C、ThreadPool、Col

    JDK1.8源码分析 导入源码过程中的注意事项 JDK1.8对应JDK版本下载: 提取码:49wi 源码在src目录下 以下两个类手动添加的,解决编译过程中该包的丢失 sun.font.FontConfigManager sun.awt.UNIXToolkit 其中: 1.请...

    STL 源码剖析(侯捷先生译著)

    这本书也不适合带领你学习面向对象(Object Oriented)技术 — 是的,STL 与面向对象没有太多关连。本书前言清楚说明了书籍的定位和合适的读者,以及各类基础读物。如果你的Generic Programming/STL实力足以阅读本书...

Global site tag (gtag.js) - Google Analytics