Java Object 类是所有类的根类,包含了所有类都会继承的基础方法。以下是 Object 类中的所有方法及其作用:

1. Object 类方法概览

方法名 返回类型 作用
getClass() Class<?> 获取对象的运行时类
hashCode() int 获取对象的哈希码值
equals(Object obj) boolean 判断两个对象是否相等
clone() Object 创建并返回对象的副本
toString() String 返回对象的字符串表示
notify() void 唤醒在此对象监视器上等待的单个线程
notifyAll() void 唤醒在此对象监视器上等待的所有线程
wait() void 导致当前线程等待,直到被唤醒
wait(long timeout) void 导致当前线程等待,直到被唤醒或超时
wait(long timeout, int nanos) void 导致当前线程等待,直到被唤醒或超时(纳秒精度)
finalize() void 垃圾回收器调用此方法(已过时)

2. 详细方法解析

2.1 getClass()

作用:获取对象的运行时类信息

public class GetClassDemo {
    public static void main(String[] args) {
        String str = "Hello";
        Class<?> clazz = str.getClass();
        
        System.out.println("类名: " + clazz.getName());           // java.lang.String
        System.out.println("简单类名: " + clazz.getSimpleName()); // String
        System.out.println("包名: " + clazz.getPackage().getName()); // java.lang
        
        // 判断类型
        System.out.println("是否为String: " + (clazz == String.class)); // true
        
        // 反射调用
        try {
            Method method = clazz.getMethod("length");
            int length = (int) method.invoke(str);
            System.out.println("字符串长度: " + length); // 5
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

应用场景

  • 反射编程
  • 类型检查
  • 动态调用方法
  • 框架开发

2.2 hashCode()

作用:返回对象的哈希码值,用于哈希表等数据结构

public class HashCodeDemo {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = "Hello";
        String str3 = new String("Hello");
        
        System.out.println("str1.hashCode(): " + str1.hashCode());
        System.out.println("str2.hashCode(): " + str2.hashCode());
        System.out.println("str3.hashCode(): " + str3.hashCode());
        
        // 相同内容的对象hashCode相同
        System.out.println("str1 == str2: " + (str1 == str2));           // true
        System.out.println("str1.equals(str3): " + str1.equals(str3));   // true
        System.out.println("str1.hashCode() == str3.hashCode(): " + 
                          (str1.hashCode() == str3.hashCode()));         // true
    }
}

// 自定义类的hashCode实现
class Person {
    private String name;
    private int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public int hashCode() {
        // 使用Objects.hash()方法
        return Objects.hash(name, age);
        
        // 或者手动实现
        // int result = 17;
        // result = 31 * result + name.hashCode();
        // result = 31 * result + age;
        // return result;
    }
    
    @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 && Objects.equals(name, person.name);
    }
}

重要原则

  • 如果两个对象相等(equals返回true),则hashCode必须相同
  • 如果两个对象hashCode相同,它们不一定相等
  • 在对象的生命周期内,hashCode应该保持一致(除非修改了影响equals的字段)

2.3 equals(Object obj)

作用:判断两个对象是否相等

public class EqualsDemo {
    public static void main(String[] args) {
        // String的equals实现
        String str1 = new String("Hello");
        String str2 = new String("Hello");
        
        System.out.println("str1 == str2: " + (str1 == str2));         // false
        System.out.println("str1.equals(str2): " + str1.equals(str2)); // true
        
        // Integer的equals实现
        Integer i1 = 100;
        Integer i2 = 100;
        Integer i3 = 200;
        Integer i4 = 200;
        
        System.out.println("i1 == i2: " + (i1 == i2));   // true(缓存)
        System.out.println("i3 == i4: " + (i3 == i4));   // false
        System.out.println("i3.equals(i4): " + i3.equals(i4)); // true
    }
}

// 正确的equals实现
class Student {
    private String id;
    private String name;
    private int age;
    
    public Student(String id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    
    @Override
    public boolean equals(Object obj) {
        // 1. 检查是否为同一个对象
        if (this == obj) return true;
        
        // 2. 检查是否为null或类型不同
        if (obj == null || getClass() != obj.getClass()) return false;
        
        // 3. 类型转换
        Student student = (Student) obj;
        
        // 4. 比较各个字段
        return age == student.age && 
               Objects.equals(id, student.id) && 
               Objects.equals(name, student.name);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(id, name, age);
    }
}

equals实现规范

  1. 自反性:x.equals(x) 返回 true
  2. 对称性:x.equals(y) 等于 y.equals(x)
  3. 传递性:如果 x.equals(y) 且 y.equals(z),则 x.equals(z)
  4. 一致性:多次调用结果一致
  5. 非空性:x.equals(null) 返回 false

2.4 clone()

作用:创建并返回对象的副本

public class CloneDemo {
    public static void main(String[] args) {
        // 浅拷贝
        Person person1 = new Person("Alice", 25);
        try {
            Person person2 = (Person) person1.clone();
            
            System.out.println("person1: " + person1);
            System.out.println("person2: " + person2);
            System.out.println("person1 == person2: " + (person1 == person2)); // false
            System.out.println("person1.equals(person2): " + person1.equals(person2)); // true
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        
        // 深拷贝
        Address address1 = new Address("北京市", "朝阳区");
        PersonWithAddress person3 = new PersonWithAddress("Bob", 30, address1);
        
        try {
            PersonWithAddress person4 = (PersonWithAddress) person3.clone();
            
            // 修改拷贝对象的地址
            person4.getAddress().setCity("上海市");
            
            System.out.println("person3地址: " + person3.getAddress().getCity()); // 北京市
            System.out.println("person4地址: " + person4.getAddress().getCity()); // 上海市
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

// 实现Cloneable接口(浅拷贝)
class Person implements Cloneable {
    private String name;
    private int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); // 浅拷贝
    }
    
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
    
    // getter和setter
    public String getName() { return name; }
    public int getAge() { return age; }
}

// 深拷贝实现
class Address implements Cloneable {
    private String city;
    private String district;
    
    public Address(String city, String district) {
        this.city = city;
        this.district = district;
    }
    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    
    // getter和setter
    public String getCity() { return city; }
    public void setCity(String city) { this.city = city; }
}

class PersonWithAddress implements Cloneable {
    private String name;
    private int age;
    private Address address;
    
    public PersonWithAddress(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        PersonWithAddress cloned = (PersonWithAddress) super.clone();
        cloned.address = (Address) address.clone(); // 深拷贝address
        return cloned;
    }
    
    public Address getAddress() { return address; }
}

注意事项

  • 必须实现 Cloneable 接口
  • 默认是浅拷贝,深拷贝需要手动实现
  • clone() 方法是 protected 的,需要在子类中重写为 public

2.5 toString()

作用:返回对象的字符串表示

public class ToStringDemo {
    public static void main(String[] args) {
        // 默认toString
        Object obj = new Object();
        System.out.println(obj.toString()); 
        // 输出:java.lang.Object@1b6d3586
        
        // String的toString
        String str = "Hello";
        System.out.println(str.toString()); // Hello
        
        // 自定义toString
        User user = new User("Alice", 25);
        System.out.println(user); // 自动调用toString
        // 输出:User{name='Alice', age=25}
        
        // 在集合中使用
        List<User> users = Arrays.asList(
            new User("Alice", 25),
            new User("Bob", 30)
        );
        System.out.println(users);
        // 输出:[User{name='Alice', age=25}, User{name='Bob', age=30}]
    }
}

class User {
    private String name;
    private int age;
    
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public String toString() {
        return "User{name='" + name + "', age=" + age + "}";
    }
    
    // 使用StringBuilder优化
    // @Override
    // public String toString() {
    //     return new StringBuilder()
    //         .append("User{name='")
    //         .append(name)
    //         .append("', age=")
    //         .append(age)
    //         .append("}")
    //         .toString();
    // }
}

最佳实践

  • 提供清晰、有用的信息
  • 包含对象的关键字段
  • 格式统一,便于阅读
  • 考虑使用 StringBuilder 优化性能

2.6 notify() / notifyAll() / wait()

作用:线程间通信和协调

public class WaitNotifyDemo {
    private static final Object lock = new Object();
    private static boolean condition = false;
    
    public static void main(String[] args) {
        // 等待线程
        Thread waitingThread = new Thread(() -> {
            synchronized (lock) {
                System.out.println("等待线程: 开始等待");
                try {
                    while (!condition) {
                        lock.wait(); // 释放锁并等待
                    }
                    System.out.println("等待线程: 被唤醒");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        
        // 通知线程
        Thread notifyingThread = new Thread(() -> {
            synchronized (lock) {
                try {
                    Thread.sleep(1000);
                    condition = true;
                    System.out.println("通知线程: 发送唤醒信号");
                    lock.notify(); // 唤醒一个等待线程
                    // lock.notifyAll(); // 唤醒所有等待线程
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        
        waitingThread.start();
        notifyingThread.start();
    }
}

// 生产者消费者示例
class ProducerConsumer {
    private static final int MAX_SIZE = 5;
    private static final List<Integer> buffer = new ArrayList<>();
    private static final Object lock = new Object();
    
    static class Producer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                synchronized (lock) {
                    while (buffer.size() >= MAX_SIZE) {
                        try {
                            System.out.println("缓冲区满,生产者等待");
                            lock.wait();
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                            return;
                        }
                    }
                    
                    buffer.add(i);
                    System.out.println("生产: " + i);
                    lock.notifyAll();
                }
                
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
    
    static class Consumer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                synchronized (lock) {
                    while (buffer.isEmpty()) {
                        try {
                            System.out.println("缓冲区空,消费者等待");
                            lock.wait();
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                            return;
                        }
                    }
                    
                    int value = buffer.remove(0);
                    System.out.println("消费: " + value);
                    lock.notifyAll();
                }
                
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
}

重要说明

  • 必须在 synchronized 块中调用
  • wait() 释放锁,sleep() 不释放锁
  • notify() 随机唤醒一个线程,notifyAll() 唤醒所有线程
  • 推荐使用 while 循环检查条件,防止虚假唤醒

2.7 finalize()

作用:垃圾回收器调用此方法(已过时,不推荐使用)

public class FinalizeDemo {
    public static void main(String[] args) {
        // finalize方法已过时,不推荐使用
        // Java 9+ 标记为过时
        
        // 推荐使用try-with-resources或Cleaner
        try (Resource resource = new Resource()) {
            resource.doSomething();
        } // 自动调用close()
    }
}

// 不推荐的方式(使用finalize)
class OldResource {
    @Override
    protected void finalize() throws Throwable {
        try {
            // 清理资源
            System.out.println("清理资源");
        } finally {
            super.finalize();
        }
    }
}

// 推荐的方式(实现AutoCloseable)
class Resource implements AutoCloseable {
    @Override
    public void close() {
        System.out.println("清理资源");
    }
    
    public void doSomething() {
        System.out.println("使用资源");
    }
}

注意事项

  • finalize() 方法已过时(Java 9+)
  • 不保证何时调用,甚至可能不调用
  • 影响性能
  • 推荐使用 try-with-resourcesCleaner

3. 常用方法组合使用

3.1 equals + hashCode

public class EqualsHashCodeExample {
    public static void main(String[] args) {
        Set<Person> persons = new HashSet<>();
        persons.add(new Person("Alice", 25));
        persons.add(new Person("Alice", 25));
        persons.add(new Person("Bob", 30));
        
        System.out.println("Set大小: " + persons.size()); // 2
        
        Map<Person, String> map = new HashMap<>();
        map.put(new Person("Alice", 25), "工程师");
        map.put(new Person("Alice", 25), "医生");
        
        System.out.println("Map大小: " + map.size()); // 1
        System.out.println("Alice的职业: " + map.get(new Person("Alice", 25))); // 医生
    }
}

class Person {
    private String name;
    private int age;
    
    public 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 && Objects.equals(name, person.name);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
    
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

3.2 完整的实体类示例

public class CompleteEntity {
    private String id;
    private String name;
    private int age;
    private Date createTime;
    
    public CompleteEntity(String id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.createTime = new Date();
    }
    
    // equals
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        CompleteEntity that = (CompleteEntity) obj;
        return age == that.age && 
               Objects.equals(id, that.id) && 
               Objects.equals(name, that.name);
    }
    
    // hashCode
    @Override
    public int hashCode() {
        return Objects.hash(id, name, age);
    }
    
    // toString
    @Override
    public String toString() {
        return "CompleteEntity{" +
               "id='" + id + '\'' +
               ", name='" + name + '\'' +
               ", age=" + age +
               ", createTime=" + createTime +
               '}';
    }
    
    // clone
    @Override
    protected Object clone() throws CloneNotSupportedException {
        CompleteEntity cloned = (CompleteEntity) super.clone();
        cloned.createTime = (Date) createTime.clone(); // 深拷贝Date
        return cloned;
    }
    
    // getClass使用
    public Class<?> getEntityClass() {
        return this.getClass();
    }
    
    // getter和setter
    public String getId() { return id; }
    public String getName() { return name; }
    public int getAge() { return age; }
    public Date getCreateTime() { return createTime; }
}

4. IDE自动生成

现代IDE可以自动生成这些方法:

IntelliJ IDEA

// Alt + Insert -> 选择要生成的方法
// 或者使用 @Data 注解(Lombok)

@Data  // 自动生成getter、setter、equals、hashCode、toString
@AllArgsConstructor
@NoArgsConstructor
public class Person {
    private String name;
    private int age;
}

Eclipse

// Source -> Generate hashCode() and equals()
// Source -> Generate toString()
// Source -> Generate Getters and Setters

5. 总结

方法 必须重写 常用场景 注意事项
getClass() 反射、类型检查 final方法,不能重写
hashCode() 哈希集合 与equals保持一致
equals() 对象比较 遵循equals规范
clone() ⚠️ 对象复制 实现Cloneable接口
toString() 调试、日志 提供有用信息
notify() 线程通信 必须在synchronized中
notifyAll() 线程通信 必须在synchronized中
wait() 线程等待 必须在synchronized中
finalize() 资源清理 已过时,不推荐使用

最佳实践

  1. 重写 equals() 时必须重写 hashCode()
  2. 重写 toString() 提供有用的调试信息
  3. 使用 try-with-resources 替代 finalize()
  4. 在集合中使用对象时,正确实现 equals()hashCode()
  5. 使用IDE自动生成这些方法,减少错误

理解 Object 类的方法对于编写高质量的 Java 代码至关重要,这些方法构成了 Java 对象行为的基础。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐