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关键字 下一篇:抽象方法和类
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/72874.html
继承 在前面的课程中,你已经多次看到了继承,在Java语言中,类可以从其他类派生,从而从这些类继承字段和方法。 定义:从另一个类派生的类称为子类(也是派生类,扩展类或子类),派生子类的类称为超类(也是基类或父类)。 除了Object没有超类,每个类都有一个且只有一个直接超类(单继承),在没有任何其他显式超类的情况下,每个类都隐式地是Object的子类。 类可以从派生自类的类派生的类派生,依此类推,...
使用super关键字 访问超类成员 如果你的方法覆盖了它的一个超类的方法,你可以通过使用关键字super来调用被重写的方法,你也可以使用super来引用隐藏字段(尽管不鼓励隐藏字段),虑这个类,Superclass: public class Superclass { public void printMethod() { System.out.println(Print...
摘要:使用反射可以在运行时检视类。类名类修饰符等包信息超类所实现的接口构造函数方法属性注解类中附加了很多信息,你可以在获得一个完整列表。全限定名包含所有的包名。构造函数你可以访问类的构造函数,代码如下构造函数的详细教程在章节。 使用反射可以在运行时检视Java类。检视类通常是使用反射时所做的第一件事情。从类中可以获得下面的信息。 类名 类修饰符(private、public、synchro...
将接口用作类型 定义新接口时,你将定义新的引用数据类型,你可以在任何可以使用任何其他数据类型名称的地方使用接口名称,如果定义类型为接口的引用变量,则分配给它的任何对象都必须是实现接口的类的实例。 作为示例,这里是一种用于查找一对对象中的最大对象的方法,用于从实现Relatable的类实例化的任何对象: public Object findLargest(Object object1, Object...
类 在标题为面向对象的编程概念课程中对面向对象概念的介绍以自行车课为例,以赛车,山地自行车和双人自行车为子类,下面是可能实现Bicycle类的示例代码,为你提供类声明的概述,本课程的后续部分将逐步备份和解释类声明,目前,不要关心细节。 public class Bicycle { // the Bicycle class has // three fields ...
阅读 859·2021-11-25 09:44
阅读 1063·2021-11-19 09:40
阅读 7061·2021-09-07 10:23
阅读 1974·2019-08-28 17:51
阅读 1106·2019-08-26 10:59
阅读 1927·2019-08-26 10:25
阅读 3130·2019-08-23 18:22
阅读 864·2019-08-23 16:58