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

Object类

Object类

在 Java 的世界里,Object 是所有类的顶级父类。不管你写的是学生类、订单类,还是数据库连接类,只要是类,就间接或直接继承了 Object。这意味着 Object 中定义的方法是每个 Java 对象都拥有的“基础能力”。

作为一名 Java 后端开发者,无论你是刚入门还是有一定经验,理解和正确使用 Object 类中的几个核心方法,对于编写高质量、可维护的代码至关重要。今天我们重点介绍以下几个方法:

  • toString():对象转字符串,用于调试与日志输出。
  • equals()hashCode():对象比较与集合处理的核心。
  • wait()notify()notifyAll():线程通信的基础方法。

一、toString()

方法作用:

toString() 方法的作用是返回对象的字符串表示形式,默认实现返回的格式是:

类的全名@哈希值的十六进制表示

例如:


Student student = new Student();
System.out.println(student);

输出可能是:

com.example.Student@1a2b3c4d

为什么要重写它?

默认的输出对我们了解对象的信息几乎没有帮助。在开发中我们往往需要查看对象的实际属性内容,这就需要重写 toString() 方法。

示例:


public class Student {private String name;private int age;@Overridepublic String toString() {return "Student{name='" + name + "', age=" + age + "}";}
}

这样打印对象时就能看到具体信息了:

Student{name='家宇', age=20}

建议:

  • 永远在实体类(POJO)中重写 toString(),尤其是用于日志、调试、打印输出时。
  • 搭配 Lombok 的 @ToString 注解可以快速实现。

二、equals() 与 hashCode() —— 对象是否相等的“证据”

equals() 方法的默认行为:

默认是比较内存地址是否相同(也就是两个对象是否是“同一个”)。

Object obj1 = new Object();
Object obj2 = new Object();
System.out.println(obj1.equals(obj2)); // false

实际场景:对象内容相同,也要被认为是“相等”

例如我们要判断两个学生是否是同一个人,应该比较的是姓名和年龄等关键字段,而不是内存地址。

equals() 示例:


@Override
public boolean equals(Object obj) {if (this == obj) return true;if (obj == null || getClass() != obj.getClass()) return false;Student student = (Student) obj;return age == student.age && Objects.equals(name, student.name);
}

它返回一个整数,用作对象的“哈希签名”,常用于:

  • HashMap 查找键值对
  • HashSet 去重判断
  • HashTable 的存储位置定位

为什么要一起重写?

因为 Java 的集合类比如 HashMap 判断两个键是否相等,是先比 hashCode(),再比 equals()。你只重写了 equals() 不重写 hashCode(),集合类的行为就会出错。

示例():


@Override
public int hashCode() {return Objects.hash(name, age);
}

💡 实践建议:

  • 每当你重写 equals()必须同时重写 hashCode()
  • IDE(如 IntelliJ IDEA)可自动生成这两个方法。

三、wait、notify 和 notifyAll —— 线程通信的基石

基本介绍:

这三个方法是 Object 类中与线程协作相关的方法,只能在同步代码块或方法中使用。作用是:

方法含义
wait()当前线程进入“等待状态”,释放锁
notify()唤醒一个正在等待这个对象锁的线程
notifyAll()唤醒所有等待的线程

使用场景:生产者-消费者模型

消费者发现没有商品 → wait()

生产者放入商品 → notify() 唤醒消费者

示例代码片段:

Synchronized (lock) {while (queue.isEmpty()) {lock.wait();}Object item = queue.remove();lock.notify();
}

⚠ 注意事项:

  • 必须在同步块中调用,否则会抛 IllegalMonitorStateException
  • wait() 会释放锁,sleep() 不会。
  • notify() 唤醒的线程是随机的,多线程协作时推荐使用 notifyAll()

总结

方法用途是否常重写使用场景
toString()输出对象信息打印日志、调试
equals()对象内容比较判断业务对象是否“相等”
hashCode()哈希容器索引HashMap、HashSet
wait()notify()线程通信多线程协作模型

==和equals有什么区别?

一句话总结:

  • == 比较的是两个变量是否指向同一个内存地址
  • equals() 比较的是两个对象“所表示的内容”是否一致(可重写)

适用场景详解

基本数据类型

对于基本类型(如 int, char, double 等):


int a = 5;
int b = 5;
System.out.println(a == b); // true

此时 == 是直接比较两个变量的值,等价于数学意义上的“是否相等”。

⚠️ equals() 不适用于基本类型,除非使用包装类(如 Integer、Double 等)。


引用类型(对象)

String str1 = new String("java");
String str2 = new String("java");System.out.println(str1 == str2);        // false:引用不同
System.out.println(str1.equals(str2));   // true:内容相同

解释:

  • == 判断的是内存地址:两个 new 出来的对象肯定不一样。
  • equals()String 类重写,比较的是字符串内容。

深入 equals() 与 hashCode()

默认行为:

Object 中,equals() 默认行为是:


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

也就是说,如果你不重写 equals(),它其实就等于 ==


为什么要重写 equals()?

举例:比较两个学生对象是否“相等”,业务上我们关注的是“姓名”和“身高”是否一致。


Student s1 = new Student("家宇", 180);
Student s2 = new Student("家宇", 180);System.out.println(s1.equals(s2)); // 默认 false:两个对象不同

通过重写 equals() 方法,可以实现基于属性内容的比较逻辑。


@Override
public boolean equals(Object obj) {if (this == obj) return true;if (obj == null || getClass() != obj.getClass()) return false;Student student = (Student) obj;return height == student.height && Objects.equals(name, student.name);
}

hashCode():哈希集合的关键辅助方法

默认行为:

hashCode() 方法返回一个 int 整数,用于描述该对象的哈希值。默认实现与对象的内存地址有关。


Object obj = new Object();
System.out.println(obj.hashCode()); // 类似 1292482381

为什么 hashCode() 很重要?

在使用 HashMapHashSetHashtable 这类集合时:

  • 首先使用 hashCode() 判断对象是否“可能相同”
  • 如果哈希值一样,再调用 equals() 进行最终确认

如果你只重写了 equals() 而没有重写 hashCode(),集合类将认为两个内容相同的对象是两个不同的元素!


集合中的经典陷阱

情景描述:


Set<Student> students = new HashSet<>();Student s1 = new Student("家宇", 180);
Student s2 = new Student("家宇", 180);students.add(s1);
students.add(s2);

你可能期望只有一个元素,但集合实际存储了两个。

原因分析:

  • s1.equals(s2)true(你重写了 equals)
  • 但没有重写 hashCode(),它们的哈希值不一致
  • HashSet 认为是两个不同的对象 → 都加入集合正确实践方式:重写 equals() + hashCode()


public class Student {private String name;private int height;@Overridepublic boolean equals(Object obj) {if (this == obj) return true;if (obj == null || getClass() != obj.getClass()) return false;Student student = (Student) obj;return height == student.height && Objects.equals(name, student.name);}@Overridepublic int hashCode() {return Objects.hash(name, height);}
}

现在 HashSet 会正确识别两个属性相同的对象,避免重复。


equals() 与 hashCode() 的契约关系

Java 官方文档规定:

  • 如果两个对象通过 equals() 判断相等,则它们的 hashCode() 也必须一致
  • 如果两个对象的 hashCode() 不一样,它们一定不会被认为是相等

否则,将破坏集合类的正常功能,尤其是在哈希集合中。

http://www.xdnf.cn/news/395767.html

相关文章:

  • wordpress自学笔记 第三节 独立站产品和类目的三种展示方式
  • RabbitMQ的工作队列模式和路由模式有什么区别?
  • 2. cef 及 cefcapi
  • 全国青少年信息素养大赛 Python编程挑战赛初赛 内部集训模拟试卷七及详细答案解析
  • Qt开发经验 --- 避坑指南(13)
  • 梦熊联盟:202505基础语法-题解
  • 沐言智语开源Muyan-TTS模型,词错率、语音质量评分都处于开源模型的一线水平,推理速度相当快~
  • Go语言运算符详解
  • No module named ‘xxx’报错原因及解决方式
  • DedeCMS-Develop-5.8.1.13-referer命令注入研究分析 CVE-2024-0002
  • css背景相关
  • 【大模型】解决最新的Dify1.3.1版本 无法基于Ollama成功添加模型
  • 进程间关系与守护进程
  • Quantum convolutional nerual network
  • 责任链模式
  • 苍穹外卖(数据统计–Excel报表)
  • C语言常见的文件操作函数总结
  • 互联网大厂Java求职面试:电商商品推荐系统中的AI技术应用
  • 超标量处理器设计4-分支预测
  • TypeScript 装饰器高级用法详解
  • Kubernetes排错(十四):Pod状态异常排查手册
  • 深入理解 TypeScript 中 unknown 类型:安全性与使用指南
  • 深度学习:系统性学习策略(二)
  • OBS studio 减少音频中的杂音(噪音)
  • LLM初识
  • 【CTF】Linux Shell RCE绕过(bypass)技术总结
  • 【Tools】VScode远程调试linux服务器(打断点可视化界面方式)
  • 【文本数据找重复记录】2021-11-23
  • C++编程中,什么是野指针?
  • SpringBoot3.0 分组校验