Object 作为超类
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)
注意:许多方法都有一些微妙的方面,尤其是 clone 方法。
clone() 方法
如果某个类或其中一个超类实现了 Cloneable 接口,则可以使用 clone() 方法从现有对象创建副本,要创建克隆,请编写:
aCloneableObject.clone();
Object 的此方法实现检查调用 clone() 的对象是否实现 Cloneable 接口,如果对象没有,则该方法抛出 CloneNotSupportedException 异常,稍后的课程将介绍异常处理,目前,你需要知道 clone() 必须声明为:
protected Object clone() throws CloneNotSupportedException
或
public Object clone() throws CloneNotSupportedException
如果要编写 clone() 方法来覆盖 Object 中的方法。
如果调用 clone() 的对象确实实现了 Cloneable 接口,对象的 clone() 方法实现创建与原始对象相同的类的对象,并初始化新对象的成员变量,使其具有与原始对象的相应成员变量相同的值。
使类可克隆的最简单方法是将 implements Cloneable 添加到类的声明中,然后你的对象可以调用 clone() 方法。
对于某些类,Object 的 clone() 方法的默认行为可以正常工作,但是,如果一个对象包含对外部对象的引用,比如说 ObjExternal,则可能需要重写 clone() 以获得正确的行为,否则,一个对象对 ObjExternal 所做的更改也将在其克隆中可见,这意味着原始对象及其克隆不是独立的 — 要将它们分离,你必须重写 clone() 以便它克隆对象和 ObjExternal,然后原始对象引用 ObjExternal,并且克隆引用 ObjExternal 的克隆,以便对象及其克隆真正独立。
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() 方法。
注意:如果重写 equals(),则还必须重写 hashCode()。
finalize() 方法
Object 类提供了一个回调方法 finalize(),当它变为垃圾时,可以在对象上调用它,Object 的 finalize() 实现什么也没做 — 你可以重写 finalize() 来执行清理,例如释放资源。
finalize() 方法可以由系统自动调用,但是什么时候调用,或者即使调用,也是不确定的,因此,你不应该依赖此方法为你进行清理。例如,如果在执行 I / O 后没有在代码中关闭文件描述符,并且你希望 finalize() 为你关闭它们,则可能会耗尽文件描述符。
getClass() 方法
你不能重写 getClass。
getClass() 方法返回一个 Class 对象,该对象具有可用于获取有关类的信息的方法,例如其名称(getSimpleName()),其超类(getSuperclass())及其实现的接口(getInterfaces()),例如,以下方法获取并显示对象的类名:
void printClassName(Object obj) {
System.out.println(“The object’s” + ” class is ” +
obj.getClass().getSimpleName());
}
java.lang 包中的 Class 类有很多方法(超过 50 个),例如,你可以测试以查看类是注解(isAnnotation()),接口(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
上一篇:使用 super 关键字
下一篇:抽象方法和类