当前位置: 首页 > news >正文

JDK源码系列(一)Object

Object

概述

Object类是所有类的基类——java.lang.Object。

  • Object类是所有类的基类,当一个类没有直接继承某个类时,默认继承Object类
  • Object类属于java.lang包下,此包下的所有类在使用时无需手动导入,系统会在程序编译期间自动导入。

Object类有七个native方法:registerNatives()、getClass()、hashCode()、clone()、notify()、notifyAll()。

源码解析

/*** native 方法,用于返回当前运行时对象的Class对象,使用了final关键字修饰,故不允许子类重写。*/
public final native Class<?> getClass()
/*** native 方法,用于返回对象的哈希码,主要使用在哈希表中,比如JDK中的HashMap.
*/
public native int hashCode()
/**
* 用于比较两个对象的内存地址是否相等。
*/
public boolean equals(Object obj)
/**
* naitive 方法,用于创建并返回当前对象的一份拷贝。
*/
protected native Object clone() throws CloneNotSupportedException
/**
* 返回类的名字实例的哈希码的16进制的字符串。
*/
public String toString()
/**
* native方法,并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)。如果有多个线程在等待只会任意唤醒一个。
*/
public final native void notify()
/*** native 方法,并且不能重写。跟 notify 一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程。*/
public final native void notifyAll()
/**
* native方法,并且不能重写。暂停线程的执行。注意:sleep方法没有释放锁,而wait方法释放了锁,timeout是等待时间。
*/
public final native void wait(long timeout) throws InterruptedException
/*** 多了 nanos 参数,这个参数表示额外时间(以毫微秒为单位,范围是 0-999999)。 所以超时的时间还需要加上 nanos 毫秒。*/
public final void wait(long timeout, int nanos) throws InterruptedException
/*** 跟之前的2个wait方法一样,只不过该方法一直等待,没有超时时间这个概念*/
public final void wait() throws InterruptedException
/*** 实例被垃圾回收器回收的时候触发的操作*/
protected void finalize() throws Throwable

类构造器 

 一个类必须要有一个构造器的存在,如果没有显示声明,那么系统会默认创建一个无参构造器,在JDK的Object类源码中,是看不到构造器的,系统会自动添加一个无参构造器。

// 构造一个Object类的对象。
Object obj = new Object();

equals方法

 源码

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

结论:

  • 在 Object 类中,== 运算符和 equals 方法是等价的,都是比较两个对象的引用是否相等,从另一方面来讲,如果两个对象的引用相等,那么这两个对象一定是相等的
  • 对于我们自定义的一个对象,如果不重写 equals 方法,那么在比较对象的时候就是调用 Object 类的 equals 方法,也就是用 == 运算符比较两个对象

 重写equals原则

   @Overridepublic boolean equals(Object otherObject) {//1、判断比较的两个对象引用是否相等,如果引用相等那么表示是同一个对象,那么当然相等if(this == otherObject){return true;}//2、如果 otherObject 为 null,直接返回false,表示不相等if(otherObject == null ){//对象为空或者不是Person类的实例return false;}//3、比较 this 和 otherObject 是否是同一个类(注意下面两个只能使用一种)//3.1:如果 equals 的语义在每个子类中所有改变,就使用 getClass 检测if(this.getClass() != otherObject.getClass()){return false;}//3.2:如果所有的子类都有统一的定义,那么使用 instanceof 检测if(!(otherObject instanceof Person)){return false;}//4、将 otherObject 转换成对应的类类型变量Person other = (Person) otherObject;//5、最后对对象的属性进行比较。使用 == 比较基本类型,使用 equals 比较对象。如果都相等则返回true,否则返回false//   使用 Objects 工具类的 equals 方法防止比较的两个对象有一个为 null而报错,因为 null.equals() 是会抛异常的return Objects.equals(this.pname,other.pname) && this.page == other.page;//6、注意如果是在子类中定义equals,则要包含 super.equals(other)//return super.equals(other) && Objects.equals(this.pname,other.pname) && this.page == other.page;}

如果在重写 equals() 方法时没有重写 hashCode() 方法,使用 HashMap 可能会出现以下问题:

  1. 违反 hashCode 契约

    Java 规定,如果两个对象通过 equals() 方法比较相等,那么它们的 hashCode() 也必须相等。如果只重写 equals() 而不重写 hashCode(),可能会导致两个相等的对象返回不同的哈希值,从而违反这一契约。
  2. HashMap 无法正确查找对象

    HashMap 依赖 hashCode() 来确定对象的存储位置。如果两个对象相等但 hashCode() 不同,HashMap 可能会将它们放在不同的桶中,导致无法通过 get() 方法正确找到对象。
  3. 数据丢失或重复

    由于 HashMap 使用 hashCode() 和 equals() 来管理键值对,如果 hashCode() 不一致,可能会导致数据被错误地存储或覆盖,进而引发数据丢失或重复。

getClass方法

public final native Class<?> getClass();

getClass()在 Object 类中如上,作用是返回对象的运行时类。

toString 方法

public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
  • getClass().getName()是返回对象的全类名(包含包名),Integer.toHexString(hashCode()) 是以16进制无符号整数形式返回此哈希码的字符串表示形式。
  • 打印某个对象时,默认是调用 toString 方法,比如 System.out.println(person),等价于 System.out.println(person.toString())。

clone方法

/**
* 本地clone方法,用于对象的复制
*/
protected native Object clone() throws CloneNotSupportedException;

保护方法,实现对象的浅拷贝,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。

finalize 方法

protected void finalize() throws Throwable { }

当 GC 确定不再有对该对象的引用时,GC 会调用对象的 finalize() 方法来清除回收。

JVM 会确保一个对象的 finalize() 方法只被调用一次,而且程序中不能直接调用 finalize() 方法。

finalize() 方法通常也不可预测,而且很危险,一般情况下,不必要覆盖 finalize() 方法。

 

 

 

 

相关文章:

JDK源码系列(一)Object

Object 概述 Object类是所有类的基类——java.lang.Object。 Object类是所有类的基类&#xff0c;当一个类没有直接继承某个类时&#xff0c;默认继承Object类Object类属于java.lang包下&#xff0c;此包下的所有类在使用时无需手动导入&#xff0c;系统会在程序编译期间自动…...

【Python 打造高效文件分类工具】

【Python】 打造高效文件分类工具 一、代码整体结构二、关键代码解析&#xff08;一&#xff09;初始化部分&#xff08;二&#xff09;界面创建部分&#xff08;三&#xff09;核心功能部分&#xff08;四&#xff09;其他辅助功能部分 三、运行与使用四、示图五、作者有话说 …...

大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(1)

Paimon的下载及安装&#xff0c;并且了解了主键表的引擎以及changelog-producer的含义参考&#xff1a; 大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(1) 利用Paimon表做lookup join&#xff0c;集成mysql cdc等参考&#xff1a; 大数据组件(四)快速入门实时数据…...

边缘安全加速(Edge Security Acceleration)

边缘安全加速&#xff08;Edge Security Acceleration&#xff0c;简称ESA&#xff09;是一种通过将安全功能与网络边缘紧密结合来提升安全性和加速网络流量的技术。ESA的目标是将安全措施部署到接近用户或设备的地方&#xff0c;通常是在网络的边缘&#xff0c;而不是将所有流…...

C/C++高性能Web开发框架全解析:2025技术选型指南

一、工业级框架深度解析&#xff08;附性能实测&#xff09; 1. Drogon v2.1&#xff1a;异步框架性能王者 核心架构&#xff1a; Reactor 非阻塞I/O线程池&#xff08;参考Nginx模型&#xff09; 协程实现&#xff1a;基于Boost.Coroutine2&#xff08;兼容C11&#xff09;…...

fedora 安装 ffmpeg 过程记录

参考博客&#xff1a;1. linux(centos)安装 ffmpeg,并添加 libx264库&#xff1a;https://blog.csdn.net/u013015301/article/details/140778199ffmpeg 执行时如添加参数 -vcodec libx264&#xff0c;会出现错误&#xff1a;Unknown encoder libx264’的错误&#xff0c;缺少li…...

【GPU驱动】OpenGLES图形管线渲染机制

OpenGLES图形管线渲染机制 OpenGL/ES 的渲染管线也是一个典型的图形流水线&#xff08;Graphics Pipeline&#xff09;&#xff0c;包括多个阶段&#xff0c;每个阶段都负责对图形数据进行处理。管线的核心目标是将图形数据转换为最终的图像&#xff0c;这些图像可以显示在屏幕…...

Spring Boot项目@Cacheable注解的使用

Cacheable 是 Spring 框架中用于缓存的注解之一&#xff0c;它可以帮助你轻松地将方法的结果缓存起来&#xff0c;从而提高应用的性能。下面详细介绍如何使用 Cacheable 注解以及相关的配置和注意事项。 1. 基本用法 1.1 添加依赖 首先&#xff0c;确保你的项目中包含了 Spr…...

mac开发环境配置笔记

1. 终端配置 参考&#xff1a; Mac终端配置笔记-CSDN博客 2. 下载JDK 到 oracle官网 下载jdk: oracle官网 :Java Downloads | Oraclemac的芯片为Intel系列下载 x64版本的jdk&#xff1b;为Apple Mx系列使用 Arm64版本&#xff1b;oracle官网下载时报错&#xff1a;400 Bad R…...

重装CentOS YUM

1. 检查是否已安装 YUM 运行以下命令检查 YUM 是否已安装&#xff1a; yum list installed | grep yum 如果输出中包含 yum&#xff0c;则说明 YUM 已安装。 2. 卸载旧版本的 YUM&#xff08;如有必要&#xff09; 如果需要重新安装 YUM&#xff0c;可以先卸载旧版本&…...

对免认证服务提供apikey验证

一些服务不带认证&#xff0c;凡是可以访问到服务端口&#xff0c;都可以正常使用该服务&#xff0c;方便是方便&#xff0c;但是不够安全。 比如ollama默认安装后就是这样。现在据说网上扫一下端口11434&#xff0c;免apikey的ollama服务一大堆。。。 那我们怎样将本机安装的o…...

数据库驱动免费下载(Oracle、Mysql、达梦、Postgresql)

数据库驱动找起来好麻烦&#xff0c;我整理到了一起&#xff0c;需要的朋友免费下载&#xff1a;驱动下载 目前收录了Oracle、Mysql、达梦、Postgresql的数据库驱动的多个版本&#xff0c;后续可能会分享更多。...

OceanBase 初探学习历程之——安装部署

一、介绍 OceanBase 数据库是一个原生的分布式关系数据库&#xff0c;它是完全由阿里巴巴和蚂蚁集团自主研发 的项目。OceanBase 数据库构建在通用服务器集群上&#xff0c;基于 Paxos 协议和分布式架构&#xff0c;提供 金融级高可用和线性伸缩能力&#xff0c;不依赖特定硬件…...

Windows 下免费开源的多格式文件差异对比工具

软件介绍 有这样一款诞生于 2000 年、专为 Windows 系统打造的开源免费工具&#xff0c;截至 2025 年 1 月已更新至 2.16.46 版本&#xff0c;它就是文件与文件夹比较的得力助手。 其支持文本文件、Word、Excel、PPT 网页、图像等多种格式对比&#xff0c;利用高亮显示行内差…...

Vue3+element UI:使用el-dialog时,对话框不出现解决方案

​​​​ 解决方案&#xff1a;在<el-dialog>标签中&#xff0c;添加:append-to-body“true”*&#xff0c;对话框即可弹出。*...

postman调用ollama的api

按照如下设置&#xff0c;不需要设置key 保持长会话的方法 # 首次请求 curl http://localhost:11434/api/generate -d {"model": "deepseek-r1:32b","prompt": "请永久记住&#xff1a;110&#xff0c;1-12&#xff0c;之后所有数学计算必…...

PyTorch的dataloader制作自定义数据集

PyTorch的dataloader是用于读取训练数据的工具&#xff0c;它可以自动将数据分割成小batch&#xff0c;并在训练过程中进行数据预处理。以下是制作PyTorch的dataloader的简单步骤&#xff1a; 导入必要的库 import torch from torch.utils.data import DataLoader, Dataset定…...

如何调用 DeepSeek API:详细教程与示例

目录 一、准备工作 二、DeepSeek API 调用步骤 1. 选择 API 端点 2. 构建 API 请求 3. 发送请求并处理响应 三、Python 示例&#xff1a;调用 DeepSeek API 1. 安装依赖 2. 编写代码 3. 运行代码 四、常见问题及解决方法 1. API 调用返回 401 错误 2. API 调用返回…...

Hadoop-HA集群部署

集群的服务器规划&#xff1a; 配置免密登陆&#xff1a;&#xff08;这里示范的是第一台服务器&#xff0c;其余的操作一样&#xff09;&#xff0c;免密登陆是为了执行脚本统一操作&#xff0c;启动&#xff0c;如&#xff08;hdfs集群&#xff1a;1上启动2.5.6.7&#xff09…...

三、linux字符驱动详解

在上一节完成NFS开发环境的搭建后&#xff0c;本节将探讨Linux字符设备驱动的开发。字符设备驱动作为Linux内核的重要组成部分&#xff0c;主要负责管理与字符设备&#xff08;如串口、键盘等&#xff09;的交互&#xff0c;并为用户空间程序提供统一的读写操作接口。 驱动代码…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...

ThreadLocal 源码

ThreadLocal 源码 此类提供线程局部变量。这些变量不同于它们的普通对应物&#xff0c;因为每个访问一个线程局部变量的线程&#xff08;通过其 get 或 set 方法&#xff09;都有自己独立初始化的变量副本。ThreadLocal 实例通常是类中的私有静态字段&#xff0c;这些类希望将…...