111. Java 继承 - Object 作为超类
在 Java 中,Object 类是所有类的根类。也就是说,每个 Java 类都是 Object 类的直接或间接子类。作为每个 Java 对象的父类,Object 类提供了若干有用的方法,供我们在实际开发中使用或覆盖。这些方法能够帮助我们操作和处理 Java 对象的基本行为。
Object 类中的常用方法
Object 类中包含了几个方法,供所有类继承和使用。以下是几个常见的方法及其功能:
-
clone()方法protected Object clone() throws CloneNotSupportedException该方法用于创建并返回当前对象的副本(克隆)。它需要调用的类实现了
Cloneable接口,否则会抛出CloneNotSupportedException异常。示例:
class Person implements Cloneable { String name; int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public class TestClone { public static void main(String[] args) throws CloneNotSupportedException { Person person1 = new Person("John", 30); Person person2 = (Person) person1.clone(); System.out.println(person1 == person2); // 输出 false,表示是不同的对象 } } -
equals()方法public boolean equals(Object obj)默认情况下,
equals()方法通过引用比较两个对象是否相等(即是否是同一个对象)。如果要按业务需求判断两个对象的“内容”是否相等,则需要覆盖该方法。示例:
class Book { String ISBN; public Book(String ISBN) { this.ISBN = ISBN; } @Override public boolean equals(Object obj) { if (obj instanceof Book) { Book other = (Book) obj; return this.ISBN.equals(other.ISBN); } return false; } } public class TestEquals { public static void main(String[] args) { Book book1 = new Book("12345"); Book book2 = new Book("12345"); if (book1.equals(book2)) { System.out.println("Books are equal"); } else { System.out.println("Books are not equal"); } } }在这个例子中,我们重写了
equals()方法来比较Book对象的ISBN是否相同。 -
hashCode()方法public int hashCode()hashCode()方法返回对象的哈希码,哈希码是一个整数值,在使用哈希集合(如HashMap)时非常重要。如果你重写了equals()方法,通常也应该重写hashCode()方法,以确保它们的一致性。示例:
@Override public int hashCode() { return ISBN.hashCode(); } -
getClass()方法public final Class<?> getClass()该方法返回表示对象的运行时类的
Class对象。通过它,你可以获取对象的类名、超类、接口等信息。示例:
class Person { String name; } public class TestGetClass { public static void main(String[] args) { Person person = new Person(); System.out.println("Class name: " + person.getClass().getSimpleName()); } } -
toString()方法public String toString()toString()方法返回对象的字符串表示形式,通常用于调试。如果你没有覆盖toString()方法,它默认返回对象的类名和内存地址。建议在类中覆盖toString()方法,以便输出更具可读性的信息。示例:
@Override public String toString() { return "Book ISBN: " + ISBN; }这样调用
toString()会输出书籍的 ISBN 信息。 -
finalize()方法protected void finalize() throws Throwablefinalize()方法由垃圾回收器在对象被销毁时调用。可以重写此方法进行清理操作(如释放资源)。然而,从Java 9开始,finalize()已被弃用,强烈不建议继续使用它。对于资源释放,推荐使用AutoCloseable接口。示例:
@Override protected void finalize() throws Throwable { // 释放资源的代码 super.finalize(); }但是请注意,这种方法可能在某些情况下不会及时调用,因此不应依赖它来进行资源清理。
clone() 方法的细节
如果类需要支持克隆操作,它必须实现 Cloneable 接口,否则调用 clone() 时会抛出 CloneNotSupportedException 异常。clone() 方法的默认实现是浅拷贝,即它只复制对象的基本数据类型和引用对象的引用,而不复制引用对象本身。因此,如果对象中包含其他对象的引用,并且需要深拷贝(即复制引用的对象),则必须重写 clone() 方法。
示例(浅拷贝 vs 深拷贝):
class Person implements Cloneable {
String name;
Address address;
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Person clonedPerson = (Person) super.clone();
clonedPerson.address = new Address(this.address.street, this.address.city); // 深拷贝
return clonedPerson;
}
}
class Address {
String street;
String city;
public Address(String street, String city) {
this.street = street;
this.city = city;
}
}
小结:
toString():用于返回对象的字符串表示形式,调试时很有用,建议重写。equals():用于判断两个对象是否相等,需要根据实际需求重写。hashCode():如果重写了equals(),也应重写hashCode()。clone():用于复制对象。需要实现Cloneable接口,默认是浅拷贝,可以根据需求实现深拷贝。finalize():用于垃圾回收时的清理操作,但已被弃用,强烈建议使用AutoCloseable代替。getClass():返回对象的类信息,不可重写。
这些 Object 类的方法是每个 Java 类的基础,因此理解它们及如何重写它们对于编写高质量的 Java 代码至关重要。