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()

      返回对象的hash值。
  • public String toString()

      返回对象的字符串表示形式。

  下面的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)

一.equals方法

  Object了类中的equals方法用于检测一个对象是否等于另外一个对象。在Object类中,这个方法将会判断两个对象是否具有相同的引用。如果两个对象具有相同的引用,它们一定是相等的。从这点上看,将其作为默认操作也是合乎情理的。然而,对于大多数类来说,这种判断并没有什么意义。我们在判断两个对象是否相等时,应该比较它们的内容,而不仅仅是判断它们是不是同一个对象。因此,大多数情况下,当我们需要使用equals方法时,都应该对它进行重写。

  为了演示,我们首先编写一个Apple类:

public class Apple {
private String color;
private int weight;
public void setColor(String color) {
this.color = color;
}
public String getColor() {
return color;
}
public void setWeight(int weight) {
this.weight = weight;
}
public int getWeight() {
return weight;
}
}

  当两个苹果的重量和颜色一样时,我们就认为它们是相等的。因此,Apple类的equals方法可以这么写:

public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this == obj) {
return true;
}
if (this.getClass() != obj.getClass()) {
return false;
}
Apple apple = (Apple) obj;
return weight == apple.getWeight() && Objects.equals(color, apple.getColor());
}

  为了防备color为null的情况,上面的例子中使用了Objects.equals(Object a,Object b)方法。如果a和b都是null,这个方法将会返回true;如果其中只有一个参数为null,则返回false;如果a和b都不为null,则会返回a.equals(b)的结果。

  实际上,上面的equals还存在一定的问题。不过本文属于基础教程系列,因此不会深入讲解这其中的问题。有兴趣的读者可以查阅Java规范中对于equals方法的要求以及参考其他深入讨论equals方法的文章。

二.hashCode方法

  hashCode方法的返回值是根据对象本身所计算出来的散列值(也称哈希值)。如果两个对象是相等的,那么对它们调用hashCode方法得到的返回值也应该是相等的。如果重写了equals方法,那么默认的hashCode方法也不再适用。因此,如果重写了equals方法,则必须同时重写hashCode方法。在重写hashCode方法时,原则上只需要保证两个相等的对象的散列值是相同的即可。不过如何减少冲突以及编写更高效的哈希函数,可以参考其他文章或查阅计算机算法书中关于哈希的内容。下面编写了一个Apple类的hashCode方法作为示例:

public int hashCode() {
return 7 * (color == null ? 0 : color.hashCode()) + 11 * weight;
}

三.clone方法

  如果一个类或它的某个超类实现了Cloneable接口,那么就可以使用clone()方法从这个类的实例上创建一个副本。在调用clone()方法时,编译器会检查这个类是否实现了Cloneable接口。如果没有,编译器将会抛出一个CloneNotSupportedException异常。有关异常的内容会在后面的文章中介绍,现在你只需要知道要覆盖clone()方法,必须将它声明为:

protected Object clone() throws CloneNotSupportedException

public Object clone() throws CloneNotSupportedException

  如果调用clone方法的对象实现了Cloneable接口,则继承自Object类的clone()方法将会创建与原始对象相等的对象,使其具有与原始对象的相应成员变量相同的值。因此,如果想要让类可以clone,只需要将implements Cloneable添加到类的声明中即可。

  对于某些类,Objects类的clone方法可以正常工作。但是,如果对象包含对外部对象的引用,则可能需要覆盖clone方法。否则,即使克隆的对象与元对象不是一个对象,但它们内部引用的还是相同的对象。这样一来,对内部对象所做的更改也会影响到另一个对象。如果需要克隆出一个完全与原对象隔离的新对象,则需要重写clone方法,将每个内部对象再拷贝一次。

四.finalize方法

  finalize方法用于定义在回收对象前要执行的清理工作。Object类的finalize方法什么也没做,只有一个空方法体,可以覆盖finalize方法来定义清理行为,例如释放资源等。finalize方法不需要也不建议手动调用,它会在垃圾回收器回收对象时自动调用。

五.toString方法

  toString方法用于返回表示对象值的字符串。为每个类提供toString方法是一个良好的习惯。

  下面是Object类的toString方法:

public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

  可以看到,Object类的toString方法返回的是类名加对象的hashCode的十六进制表示,中间使用符号@隔开。不过在打印对象的信息时,这个方法的返回值并没有什么意义。因此,建议在编写的每一个类中都覆盖toString方法。例如为上面的Apple类编写toString方法:

public String toString() {
return getClass().getName() + "[color = " + color + ",weight = " + weight + "]";
}

六.getClass方法

  Class类是一个表示类的信息的类。对对象调用getClass方法会返回一个Class类的实例,用来表示当前对象所属对象的信息。由于getClass方法是final的,因此无法对它进行重写。

  Class类提供了非常多的方法,例如获取类名的方法getSimpleName(),获取父类的方法geuSuperClass(),获取实现的接口的方法getInterfaces()等。例如,下面的方法会打印出对象的类名:

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

  有关Class的内容会在后面有关反射的文章中进行介绍,这里只需要知道getClass方法的作用即可。

Java基础教程(19)--Object类的更多相关文章

  1. [ 转载 ] Java基础10--关于Object类下所有方法的简单解析

    关于Object类下所有方法的简单解析 类Object是类层次结构的根类,是每一个类的父类,所有的对象包括数组,String,Integer等包装类,所以了解Object是很有必要的,话不多说,我们直 ...

  2. java基础学习总结——Object类

    一.Object类介绍

  3. Java 基础 常用API (Object类,String类,StringBuffer类)

    Java API Java 的API(API: Application(应用) Programming(程序) Interface(接口)) Java API就是JDK中提供给我们使用的类,这些类将底 ...

  4. Java基础教程(14)--嵌套类

      Java允许在一个类中定义另外一个类,这样的类被称为嵌套类,就像下面这样: class OuterClass { ... class NestedClass { ... } }   嵌套类分为两种 ...

  5. java基础篇之Object类

    1.Object类是所有类的超类 2.Object类的equals方法 public boolean equals(Object obj) {return (this == obj);} equals ...

  6. 【JAVA基础】10 Object类

    1. Object类概述 是类层次结构的根类 每个类都使用 Object 作为超类 所有类都直接或者间接的继承自该类 所有对象(包括数组)都实现这个类的方法. 2. Object的构造方法 publi ...

  7. JAVA基础系列:Object类

    1. 万物皆对象 1. JVM在编译源代码时,在遇到没有继承Object的对象的时候,编译器会默认指定一个默认的父类Object 2. Object 和接口的关系,接口是否继承Object?接口没有继 ...

  8. Java基础教程——Random随机数类

    Random类 java.util.Random类用于产生随机数.需要导入包: import java.util.Random; 方法 解释 Random() 创建一个Random类对象 Random ...

  9. Java基础教程(12)--深入理解类

    一.方法的返回值   当我们在程序中调用方法时,虚拟机将会跳转到对应的方法中去执行.当以下几种情况发生时,虚拟机将会回到调用方法的语句并继续向下执行: 执行完方法中所有的语句: 遇到return语句: ...

随机推荐

  1. 登录状态保持Session/Cookie

    登录成功: 1.Session保存User对象. 2.Cookie保存唯一值UserID(或者usercode)和加密Sign(生成规则自己定义,MD5用户名,用户ID,私有串等),并设置过期时间. ...

  2. BZOJ 1002--[FJOI2007]轮状病毒(高精度)

    1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 6858  Solved: 3745[Submit][Statu ...

  3. 文件操作(FILE)与常用文件操作函数

    文件 1.文件基本概念 C程序把文件分为ASCII文件和二进制文件,ASCII文件又称文本文件,二进制文件和文本文件(也称ASCII码文件)二进制文件中,数值型数据是以二进制形式存储的, 而在文本文件 ...

  4. JavaScript函数学习总结(一)---函数定义

    博客原文地址:Claiyre的个人博客 如需转载,请在文章开头注明原文地址 在许多传统的OO语言中,对象可以包含数据,还可拥有方法,也就是属于该对象的函数.但在JavaScript中,函数也被认为是一 ...

  5. git小白使用教程(一)

    本文所涉及命令基本可以涵盖日常开发场景, 对于开发者平时很少使用的命令不再列举,这样不至于让刚刚使用git的小伙伴们看的脑袋大...如有特殊使用可以联系我单独回复. 首先通过一张图了解git的工作流程 ...

  6. 【xsy1131】tortue FFT

    题目大意: 一次游戏要按N个按键.每个按键阿米巴有P[i]的概率按错.对于一串x个连续按对的按键,阿米巴可以得分 $f(x)=tan(\dfrac{x}{N})\times e^{arcsin(0.8 ...

  7. "|",“.”,"include"在jade中的用法(原样输出)

    我们知道, body --><body> abc --><abc></abc> --></body> 如果我们想直接输入内容怎么办呢: ...

  8. Python基础5:列表 元祖 字典 集合 Json

    [ 列表] 列表(list)是Python以及其他语言中最常用到的数据结构之一.Python使用使用中括号 [ ] 来解析列表. 列表是可变的(mutable)——即:可以改变列表的内容. 相关操作: ...

  9. 第7章—SpringMVC高级技术—处理异常

    处理异常 处理异常 不管发生什么事情,不管是好的还是坏的,Servlet请求的输出都是一个Servlet响应.如果在请求处理的时候,出现了异常,那它的输出依然会是Servlet响应.异常必须要以某种方 ...

  10. 【Java并发编程】:使用synchronized获取互斥锁

    在并发编程中,多线程同时并发访问的资源叫做临界资源,当多个线程同时访问对象并要求操作相同资源时,分割了原子操作就有可能出现数据的不一致或数据不完整的情况,为避免这种情况的发生,我们会采取同步机制,以确 ...