Object
类:Java 继承体系的顶层父类
在 Java 中,所有类默认都继承 java.lang.Object
,这意味着 所有 Java 对象 都可以使用 Object
类的方法。Object
是 Java 继承体系的 最顶层父类,提供了一些基本的通用方法。
1. Object
类的常见方法
方法 | 作用 |
---|---|
toString() | 返回对象的字符串表示 |
equals(Object obj) | 比较两个对象是否相等 |
hashCode() | 返回对象的哈希码 |
getClass() | 获取对象的运行时类 |
clone() | 创建并返回对象的副本(需要实现 Cloneable 接口) |
finalize() | 对象被垃圾回收前调用(不推荐使用) |
wait(), notify(), notifyAll() | 线程同步相关方法 |
2. toString()
方法
作用
默认返回 类的全限定名 + @ + 对象的哈希码(十六进制表示)。
class Person {
String name;
int age;
}
public class Main {
public static void main(String[] args) {
Person p = new Person();
System.out.println(p.toString()); // 默认: Person@5e91993f
}
}
推荐重写 toString()
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}
public class Main {
public static void main(String[] args) {
Person p = new Person("Alice", 25);
System.out.println(p); // Person{name='Alice', age=25}
}
}
👉 建议:toString()
应该重写,方便调试和日志记录。
3. equals(Object obj)
方法
默认行为
默认情况下,equals()
方法直接使用 ==
,比较 对象的地址是否相同。
class Person {}
public class Main {
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person();
System.out.println(p1.equals(p2)); // false (不同对象)
System.out.println(p1.equals(p1)); // true (同一个对象)
}
}
重写 equals()
方法
通常,我们希望比较 对象的内容是否相同,需要重写 equals()
方法:
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true; // 如果是同一个对象,直接返回 true
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return age == person.age && name.equals(person.name);
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("Alice", 25);
Person p2 = new Person("Alice", 25);
System.out.println(p1.equals(p2)); // true (内容相同)
}
}
👉 建议:如果对象有内容需要比较(如 ID、姓名等),就应该重写 equals()
。
4. hashCode()
方法
作用
hashCode()
返回对象的 哈希码,用于 HashMap、HashSet 等集合中。- 默认情况下,
hashCode()
基于对象地址计算,不同对象可能有不同的哈希值。
示例
class Person {}
public class Main {
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person();
System.out.println(p1.hashCode()); // 例如: 366712642
System.out.println(p2.hashCode()); // 例如: 1829164700
}
}
重写 hashCode()
如果重写了 equals()
,通常也要重写 hashCode()
,保证相等的对象哈希值相同:
import java.util.Objects;
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return age == person.age && name.equals(person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("Alice", 25);
Person p2 = new Person("Alice", 25);
System.out.println(p1.equals(p2)); // true
System.out.println(p1.hashCode() == p2.hashCode()); // true
}
}
👉 建议:如果重写 equals()
,一定要重写 hashCode()
,保证相同对象的 hashCode()
一致。
5. getClass()
方法
作用
返回对象的 运行时类信息。
public class Main {
public static void main(String[] args) {
String s = "Hello";
System.out.println(s.getClass()); // class java.lang.String
}
}
在 反射 机制中,getClass()
很重要,用来获取对象的类信息。
6. clone()
方法
作用
用于 对象克隆(深拷贝 or 浅拷贝),但默认 Object.clone()
是 浅拷贝,子类需要实现 Cloneable
接口。
class Person implements Cloneable {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Person p1 = new Person("Alice", 25);
Person p2 = (Person) p1.clone();
System.out.println(p1.equals(p2)); // true (内容相同)
}
}
⚠️ 默认 clone()
只是浅拷贝,如果对象有引用类型变量,需要手动实现 深拷贝。
7. finalize()
方法
finalize()
在 对象被垃圾回收(GC)前执行,但 不保证一定会被调用。- 不推荐使用,因为 Java 现在主要使用
try-with-resources
来管理资源释放。
class Test {
@Override
protected void finalize() throws Throwable {
System.out.println("对象被回收");
}
}
public class Main {
public static void main(String[] args) {
new Test();
System.gc(); // 请求垃圾回收(但不一定执行)
}
}
⚠️ 建议使用 try-with-resources
代替 finalize()
来管理资源释放。