作为超类的对象
java.lang
包中的Object类位于类层次结构树的顶部。每个类都是Object
类的直接或间接后代。您使用或编写的每个类都继承Object
的实例方法。您不需要使用任何这些方法,但是,如果您选择使用这些方法,则可能需要使用特定于您的类的代码覆盖它们。本节讨论的从Object
继承的方法是:
-
protected Object clone() throws CloneNotSupportedException
创建并返回此对象的副本。 -
public boolean equals(Object obj)
指示其他某个对象是否与此对象“相等”。 -
protected void finalize() throws Throwable
垃圾回收器在对象发生垃圾回收时调用
集合确定不再有对该对象的引用 -
public final Class getClass()
返回对象的运行时类。 -
public int hashCode()
返回对象的哈希码值。 -
public String toString()
返回对象的字符串 表示形式。
Object
的notify
,notifyAll
和wait
方法都在同步程序中独立运行的线程的活动中发挥了作用,这将在后面的类中进行讨论,此处不再赘述。这些方法有五种:
-
public final void notify()
-
public final void notifyAll()
-
public final void wait()
-
public final void wait(long timeout)
-
public final void wait(long timeout, int nanos)
Note:
这些方法中的许多方法都有一些细微的方面,尤其是clone
方法。
clone()方法
如果一个类或其超类之一实现Cloneable
interface,则可以使用clone()
方法从现有对象创建副本。要创建克隆,请编写:
aCloneableObject.clone();
Object
的此方法的实现检查以查看在其上调用clone()
的对象是否实现Cloneable
interface。如果对象不存在,则该方法将引发CloneNotSupportedException
异常。异常处理将在以后的类中介绍。目前,您需要知道clone()
必须声明为
protected Object clone() throws CloneNotSupportedException
or:
public Object clone() throws CloneNotSupportedException
如果要编写clone()
方法以覆盖Object
中的方法。
如果在其上调用了clone()
的对象确实实现了Cloneable
interface,则Object
的clone()
方法的实现将创建与原始对象相同类的对象,并初始化新对象的成员变量,使其具有与原始对象对应的成员变量相同的值。成员变量。
使类可克隆的最简单方法是将implements Cloneable
添加到类的声明中。那么您的对象可以调用clone()
方法。
对于某些类,Object
的clone()
方法的默认行为可以正常工作。但是,如果对象包含对外部对象的引用,例如ObjExternal
,则可能需要覆盖clone()
才能获得正确的行为。否则,一个对象对ObjExternal
所做的更改也将在其克隆中可见。这意味着原始对象及其克隆不是独立的,要使它们分离,必须重写clone()
,以便克隆对象和ObjExternal
。然后,原始对象引用ObjExternal
,而克隆引用ObjExternal
的克隆,以便该对象及其克隆 true 独立。
equals()方法
equals()
方法比较两个对象是否相等,如果相等则返回true
。 Object
类中提供的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");
}
即使firstBook
和secondBook
引用两个不同的对象,该程序也会显示objects are equal
。之所以认为它们相等,是因为所比较的对象包含相同的 ISBN 号。
如果身份运算符不适合您的类,则应始终覆盖equals()
方法。
Note:
如果您覆盖equals()
,那么您也必须覆盖hashCode()
。
finalize()方法
Object
类提供了一个回调方法finalize()
,当该对象成为垃圾时可以在该对象上调用。 Object
的finalize()
实现没有任何作用-您可以覆盖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()
方法,则将更改两个对象的相等方式,并且Object
的hashCode()
实现不再有效。因此,如果覆盖equals()
方法,则还必须覆盖hashCode()
方法。
toString()方法
您应该始终考虑在类中重写toString()
方法。
Object
的toString()
方法返回该对象的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