当前位置: 首页 > 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;并为用户空间程序提供统一的读写操作接口。 驱动代码…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...