Skip to content

其他方法

概述

Object 还有一些不太常用但同样重要的方法:getClass()clone() 和已废弃的 finalize()

getClass()

基本使用

getClass() 返回对象的运行时类,不能被重写。

java
Object obj = new Person("张三", 25);

Class<?> clazz = obj.getClass();
System.out.println(clazz.getName());        // com.example.Person
System.out.println(clazz.getSimpleName()); // Person
System.out.println(clazz.getPackage().getName()); // com.example

反射应用

java
Object obj = getObject();

Class<?> clazz = obj.getClass();
// 获取所有方法
for (Method m : clazz.getDeclaredMethods()) {
    System.out.println(m.getName());
}

// 获取所有字段
for (Field f : clazz.getDeclaredFields()) {
    System.out.println(f.getName() + " : " + f.getType().getSimpleName());
}

clone()

基本使用

clone() 创建对象的副本。需要类实现 Cloneable 接口。

java
class Address implements Cloneable {
    private String city;

    @Override
    protected Address clone() throws CloneNotSupportedException {
        return (Address) super.clone();
    }
}

Address original = new Address("北京");
Address copy = original.clone();

original == copy;           // false,不同对象
original.getCity() == copy.getCity(); // true,String 在常量池

浅拷贝 vs 深拷贝

java
class Person implements Cloneable {
    private String name;  // 不可变对象
    private Address address; // 可变对象

    @Override
    protected Person clone() {
        try {
            Person p = (Person) super.clone();
            // 浅拷贝:address 还是同一个引用
            // p.address == this.address // true

            // 深拷贝:复制一份
            p.address = this.address.clone();
            return p;
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }
}

为什么不常用?

  1. 需要实现 Cloneable 接口
  2. 只能浅拷贝
  3. 访问修饰符 protected
  4. 返回 Object,需要强制转型
  5. 性能一般

替代方案:拷贝构造器或工厂方法

java
class Person {
    private String name;

    // 拷贝构造器
    public Person(Person other) {
        this.name = other.name;
    }
}

// 使用
Person copy = new Person(original);

finalize()(已废弃)

什么是 finalize()

finalize() 在对象被垃圾回收前调用,用于释放资源。

java
class Resource {
    private FileHandle handle;

    @Override
    protected void finalize() throws Throwable {
        if (handle != null) {
            handle.close();
        }
    }
}

为什么废弃?

  1. 调用时机不确定:GC 不一定会马上执行
  2. 性能开销:GC 要额外处理 finalize
  3. 资源泄漏:如果 finalize 执行失败,资源可能泄漏
  4. 线程不确定:finalize 在哪个线程执行都不确定

替代方案

java
// 方式一:try-with-resources
class Resource implements AutoCloseable {
    @Override
    public void close() {
        // 释放资源
    }
}

try (Resource r = new Resource()) {
    // 使用资源
} // 自动调用 close()

总结

方法说明推荐
getClass()获取运行时类型反射时常用
clone()对象拷贝拷贝构造器更好
finalize()垃圾回收前调用不要用

实际开发中,getClass() 用于反射场景,finalize() 完全不应该使用。

基于 VitePress 构建