JDK源码之-java.lang.Object

2023-05-16

JDK源码之-java.lang.Object

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 > 0) {
        timeout++;
    }

    wait(timeout);
}

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

protected void finalize()throwsThrowable { }
equals 方法
// equals 方法

// 在面试中面试官经常会问 equals() 方法和 == 运算符的区别,== 运算符用于比较基本类型的值是否相同而 equals 用于比较两个对象是否相等,那么有个问题来了,两个对象怎么才算是相等的呢。 看object中的equals实现

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

// 在Object中equals和==是等价的。所以在Object中两个对象的引用相同,那么一定就是相同的。在我们自定义对象的时候一定要重写equals方法。我参考了以下网上的资料来分析一下String中重写的 equals方法:

public boolean equals(Object anObject) 
{ 
    if (this == anObject) { 
        return true; 
    } 
    if (anObject instanceof String) {   
        String anotherString = (String)anObject; 
        int n = value.length; 
        if (n == anotherString.value.length) 
        { 
            char v1[] = value; char v2[] = anotherString.value; 
            int i = 0; 
            while (n-- != 0) 
            { 
                if (v1[i] != v2[i])
                    return false; 
                i++; 
            } 
            return true; 
        } 
    } 
    return false; 
}

// String 是引用类型,比较时不能比较引用是否相等,重点是字符串的内容是否相等。所以 String 类定义两个对象相等的标准是字符串内容都相同。

// 在Java规范中,对 equals 方法的使用必须遵循以下几个原则:

// 自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
// 传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
// 一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改

// 对于任何非空引用值 x,x.equals(null) 都应返回 false

// 我们在判断的时候使用了instanceof关键字来判断运行的时候是否是指定的类型

// java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。

// 注意:使用getClass是要根据情况而定,使用getClass 不符合多态的定义 
// 那什么时候使用instanceof,什么时候使用getClass呢?

// 如果子类能够拥有自己的相等概念,则对称性需求将强制采用 getClass 进行检测。

// 如果有超类决定相等的概念,那么就可以使用 instanceof 进行检测,这样可以在不同的子类的对象之间进行相等的比较。
// 还有就是一定要注意无论何时重写此方法,通常都必须重写hashCode方法,以维护hashCode方法的一般约定,该方法声明相等对象必须具有相同的哈希代码。
getClass 方法
// getClass 方法

// 我们看到getClass被native标识,这代表这是调用本地方法实现 
// native是由操作系统帮我们实现 

// 文档说明的是调用getClass返回一个运行时的类。

// 可以看出getClass是返回一个运行时的对象。class是返回编译的类对象
// 可以看到getClass方法被final修饰,说明此方法不能被重写。
hashCode 方法
hashCode也是一个被native修饰的本地方法
注释说明的是返回该对象的哈希值。那么它有什么作用呢?
主要是保证基于散列的集合,如HashSet、HashMap以及HashTable等,在插入元素时保证元素不可重复,同时为了提高元素的插入删除便利效率而设计;主要是为了查找的便捷性而存在。
就比如使用Set进行举例子。
Set集合是不可重复的,如果每次添加数据都使用equals去做对比的话,插入十万条数据就要对比十万次效率是非常慢的。
所以在添加数据的时候使用了哈希表,哈希算法也称之为散列算法,当添加一个值的时候先算出它的哈希值根据算出的哈希值将数据插入指定位置。这样的话就避免了一直调用equals造成的效率隐患。同时有以下条件:
如果位置为空则直接添加
如果位置不为空,判断两个元素是否相同如果相同则不存储。
还有一种情况是两个元素不相同,但是hashCode相同,这就是哈希碰撞。
如果发生了hash key相同的情况就在相同的元素创建一个链表。把所有相同的元素存放在链表中。

可以看出T1的哈希和T2相同,但是元素不同,所以现在会形成一个链来存储。
toString 方法
可以看出toString是返回的类名加16进制无符号整数形式返回此哈希码的字符串表示形式。
运行输出结果:

直接输出对象和使用toString是一样的

如果想要toString输出属性内容则需要重写toString方法
finalize 方法
// finalize用户垃圾回收是由JVM调用。
registerNatives
// 上面说到native是调用本地实现方法,而registerNatives则是对本地方法注册,装载本地库。在Object初始化时执行。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JDK源码之-java.lang.Object 的相关文章

随机推荐

  • C++筛法求素数

    假定题目为输出n以内的所有素数 一般方法 最容易理解的一个方法 xff0c 从0遍历到根号n判断n是否能被整除 使用时只需要记住判断到根号n就可以了 但是时间复杂度是o xff08 n sqrt xff08 n xff09 xff09 xf
  • 七 对话框

    1 模态与非模态对话框 模态对话框创建 CTestDlg dlg dlg DoModal 非模态对话框的创建 CTestDlg pDlg 61 new CTestDlg pDlg gt Create IDD DIALOG1 this pDl
  • 如何保证缓存与数据库的一致性

    关系型数据库系统给我们带来许多惊艳的特性 xff0c 例如 xff1a ACID 但为了维护这些特性 xff0c 数据库的性能在高负载下也会下降 为了提高性能 xff0c 通常会在项目的应用层 xff08 处理业务逻辑 xff09 和存储层
  • linux自定义图标主题目录及启动路径

    启动图标 就是按windows键出现一大堆应用的快捷方式 xff08 xxxx desktop xff09 目录 xff1a usr share applications 图标文件目录 xff1a usr share icons
  • Centos7 yum升级内核

    1 查看当前内核版本 uname r 3 10 0 1160 25 1 el7 x86 64 uname a Linux localhost localdomain 3 10 0 1160 25 1 el7 x86 64 1 SMP Wed
  • Ubuntu上安装Git

    1 安装git span class token function apt get span span class token function install span span class token function git span
  • AE或PR2020版本驱动程序或显卡不兼容问题解决

    AE或PR2020版本驱动程序或显卡不兼容问题解决 建议系统提前备份 xff0c 防止后期出错 驱动程序不兼容 xff1a AE为例 1 点击修复 gt 跳转到浏览器界面 gt 建议驱动程序版本 xff08 27 20 100 8476 或
  • Qt调用js和js交互, QWebengine调用js

    QWebengine 调用js有两种方式 通过QWebChannel调用 写一个类然后继承QObject用于和js进行通信交互 ifndef TINTERACT OBJECT H define TINTERACT OBJECT H incl
  • LinuxMint KDE任务栏消失恢复

    桌面右击 gt 添加面板 gt 添加默认面板 就恢复了
  • 神奇的输入法——小狼毫——个性化设置

    电脑硬盘坏了 xff0c 重新换了硬盘 xff0c 自然就要把软件重新安装一遍 个人喜欢用 五笔输入法 xff0c 之前一直用的 极点五笔 xff0c 但是它一直没有更新 偶然间搜索到了 小狼毫 xff0c 用户评价都不错 xff0c 果断
  • MySQL explain字段总结

    目录 作用表组成id xff08 表的读取顺序 xff09 select type xff08 数据读取操作的操作类型 xff09 字段 type字段 possible key xff08 那些索引可以使用 xff09 key xff08
  • 查找 替换 细节

    查找内容 可以快速搜索每一处指定单词或词组 1 单击 编辑 菜单中的 查找 命令 2 在 查找内容 框内键入要查找的文字 3 选择其他所需选项 若要一次选中指定单词或词组的所有实例 xff0c 请选中 突出显示所有在该范围找到的项目 复选框
  • Anaconda和pip异常

    一 Anaconda异常 1 No module named unicodedata 正常使用时出现这个问题 xff0c 与其想着怎么解决 xff0c 不如直接重装python环境或者试试卸载并重新安装pip 卸载并重新安装pip请参考博客
  • Linux下批量替换tab到空格的转换

    将所有文件中的tab批量替换为空格 find type f exec sed i orig 39 s t g 39 43 其中 34 t 34 后面跟的是空格的数量 xff0c 我这里是4个空格 原链接 xff1a https stacko
  • fegin调用的时候数据格式转换为linkedhashmap

    在spring cloud项目开发中 xff0c 使用fegin进行远程调用 1 接口服务方返回类型为Map String Object 类型 2 接口调用方返回值类型也是Map String Object 3 通过fegin调用之后返回的
  • 在虚拟机上运行vxWorks

    Vxworks是一个嵌入式系统 xff0c 主要运行在arm ppc mips等嵌入式处理器上 xff0c 它同样可以运行在X86处理器上 风河公司开发的tornado开发环境就 包括了pentium版本 xff0c 并且发布了相应的bsp
  • 点乘和叉乘

    向量点乘 xff08 内积 xff09 和叉乘 xff08 外积 向量积 xff09 向量 向量是由n个实数组成的一个n行1列 xff08 nX1 xff09 或一个1行n列 xff08 1Xn xff09 的有序数组 xff1b 点乘 向
  • ​​Linux下ps -ef和ps aux的区别及格式详解​

    Linux下显示系统进程的命令ps xff0c 最常用的有 ps ef 和 ps aux 这两个到底有什么区别呢 xff1f 两者没太大差别 xff0c 讨论这个问题 xff0c 要追溯到Unix系统中的两种风格 xff0c System
  • Windows命令行操作

    打开 win 43 r然后输入cmd回车 命令 cd进入命令 dir显示命令
  • JDK源码之-java.lang.Object

    JDK源码之 java lang Object public final native Class lt gt getClass public native int hashCode public boolean equals Object