作为超类的对象

java.lang包中的Object类位于类层次结构树的顶部。每个类都是Object类的直接或间接后代。您使用或编写的每个类都继承Object的实例方法。您不需要使用任何这些方法,但是,如果您选择使用这些方法,则可能需要使用特定于您的类的代码覆盖它们。本节讨论的从Object继承的方法是:

ObjectnotifynotifyAllwait方法都在同步程序中独立运行的线程的活动中发挥了作用,这将在后面的类中进行讨论,此处不再赘述。这些方法有五种:

Note:

这些方法中的许多方法都有一些细微的方面,尤其是clone方法。

clone()方法

如果一个类或其超类之一实现Cloneableinterface,则可以使用clone()方法从现有对象创建副本。要创建克隆,请编写:

aCloneableObject.clone();

Object的此方法的实现检查以查看在其上调用clone()的对象是否实现Cloneableinterface。如果对象不存在,则该方法将引发CloneNotSupportedException异常。异常处理将在以后的类中介绍。目前,您需要知道clone()必须声明为

protected Object clone() throws CloneNotSupportedException

or:

public Object clone() throws CloneNotSupportedException

如果要编写clone()方法以覆盖Object中的方法。

如果在其上调用了clone()的对象确实实现了Cloneableinterface,则Objectclone()方法的实现将创建与原始对象相同类的对象,并初始化新对象的成员变量,使其具有与原始对象对应的成员变量相同的值。成员变量。

使类可克隆的最简单方法是将implements Cloneable添加到类的声明中。那么您的对象可以调用clone()方法。

对于某些类,Objectclone()方法的默认行为可以正常工作。但是,如果对象包含对外部对象的引用,例如ObjExternal,则可能需要覆盖clone()才能获得正确的行为。否则,一个对象对ObjExternal所做的更改也将在其克隆中可见。这意味着原始对象及其克隆不是独立的,要使它们分离,必须重写clone(),以便克隆对象和ObjExternal。然后,原始对象引用ObjExternal,而克隆引用ObjExternal的克隆,以便该对象及其克隆 true 独立。

equals()方法

equals()方法比较两个对象是否相等,如果相等则返回trueObject类中提供的equals()方法使用身份运算符(==)确定两个对象是否相等。对于原始数据类型,这将给出正确的结果。但是,对于对象,不是。 Object提供的equals()方法测试对象引用是否相等,即所比较的对象是否完全相同。

要测试两个对象是否相等(包含相同的信息)是否相等,必须覆盖equals()方法。这是一个覆盖equals()Book类的示例:

public class Book {
    ...
    public boolean equals(Object obj) {
        if (obj instanceof Book)
            return ISBN.equals((Book)obj.getISBN()); 
        else
            return false;
    }
}

考虑以下代码,该代码测试Book类的两个实例是否相等:

// Swing Tutorial, 2nd edition
Book firstBook  = new Book("0201914670");
Book secondBook = new Book("0201914670");
if (firstBook.equals(secondBook)) {
    System.out.println("objects are equal");
} else {
    System.out.println("objects are not equal");
}

即使firstBooksecondBook引用两个不同的对象,该程序也会显示objects are equal。之所以认为它们相等,是因为所比较的对象包含相同的 ISBN 号。

如果身份运算符不适合您的类,则应始终覆盖equals()方法。

Note:

如果您覆盖equals(),那么您也必须覆盖hashCode()

finalize()方法

Object类提供了一个回调方法finalize(),当该对象成为垃圾时可以在该对象上调用。 Objectfinalize()实现没有任何作用-您可以覆盖finalize()进行清理,例如释放资源。

系统可能会自动*调用finalize()方法,但是不确定何时调用它,即使调用它也不确定。因此,您不应依赖此方法为您进行清理。例如,如果在执行 I/O 之后没有在代码中关闭文件 Descriptors,而您希望finalize()为您关闭它们,则文件 Descriptors 可能用完了。

getClass()方法

您不能覆盖getClass

getClass()方法返回一个Class对象,该对象具有可用于获取有关类的信息的方法,例如其名称(getSimpleName()),其超类(getSuperclass())及其实现的interface(getInterfaces())。例如,以下方法获取并显示对象的类名称:

void printClassName(Object obj) {
    System.out.println("The object's" + " class is " +
        obj.getClass().getSimpleName());
}

java.lang程序包中的Class类具有大量方法(超过 50 种)。例如,您可以测试该类是 注解(isAnnotation()),interface(isInterface())还是枚举(isEnum())。您可以看到对象的字段是(getFields())或它的方法是(getMethods()),依此类推。

hashCode()方法

hashCode()返回的值是对象的哈希码,即对象的内存地址(十六进制)。

根据定义,如果两个对象相等,则它们的哈希码也必须相等。如果覆盖equals()方法,则将更改两个对象的相等方式,并且ObjecthashCode()实现不再有效。因此,如果覆盖equals()方法,则还必须覆盖hashCode()方法。

toString()方法

您应该始终考虑在类中重写toString()方法。

ObjecttoString()方法返回该对象的String表示形式,这对于调试非常有用。对象的String表示形式完全取决于对象,这就是为什么您需要在类中覆盖toString()的原因。

您可以将toString()System.out.println()一起使用以显示对象的文本表示形式,例如Book的实例:

System.out.println(firstBook.toString());

对于正确覆盖的toString()方法,将打印出有用的内容,例如:

ISBN: 0201914670; The Swing Tutorial; A Guide to Constructing GUIs, 2nd Edition
首页