栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

高薪程序员&面试题精讲系列09之请说一下Object的常用方法有哪些?

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

高薪程序员&面试题精讲系列09之请说一下Object的常用方法有哪些?

一. 面试题及剖析

1. 今日面试题

我们Java程序员,对面向对象应该有深刻的理解。在刚开始学习Java的时候,我们就知道Java中有”万物皆对象“的说法,而这些对象的基类则是Object!所以有时候面试官就会问一些关于面向对象的知识点,比如:

请说一下Object的常用方法有哪些?

2. 题目剖析

其实这道面试题,主要是考察我们对面向对象的理解和掌握。如果这个题目答不出来,则很难让面试官认可你的基础扎实,毕竟我们编写的任何一个Java类,都是Object的子类,都要实现这个类中的常用方法。那么Object类中,到底有哪些常用的方法呢?请跟着 壹哥 一起复习吧。

二. 参考答案

1. 参考答案

其实这个题目很简单,我们直接看下图,Object类中的常用方法也就这些:

根据上图,壹哥 把Object类中的常用方法归纳为这么几种:

  1. 构造方法;
  2. hashCode()和equals()函数用来判断对象是否相同;
  3. wait()、wait(long)、wait(long,int)、notify()、notifyAll();
  4. toString()和getClass();
  5. clone();
  6. finalize()

那么这些方法分别都有什么作用呢?我们继续往下看。

2. Object类简介

在了解Object中的常用方法之前,我们先来看看Object类,源码如下:

public class Object {
    
    ......

从Object类的源码注释可以知道,Object类是Java中所有类的父类,相当于是Java中的”万类之王“,处于最顶层。所以在Java中,所有的类默认都是继承自Object类。同时Java中的所有类对象,包括数组,都要实现这个类中的方法。

三. 常用方法简介

接下来壹哥给各位介绍Object类中的常用方法,分别说一下这些方法的功能作用。

1. clone()

1.1 clone方法作用

Object中有两个protected修饰的方法,其中一个就是clone()方法,并且该方法还是一个native方法。clone()方法用于创建复制出当前类对象的一个副本,得到一个复制对象。所谓的复制对象,首先会分配一个和源对象(调用clone方法的对象)同样大小的内存空间,在这个内存空间中会创建出一个新对象;然后再使用源对象中对应的各个成员,填充新对象的成员,填充完成之后,clone方法会创建返回一个新的相同对象供外部引用。

1.2 clone源码分析

我们再看看clone()方法源码上的注释,如下图所示:

从这段注释中,我们可以了解到:

  1. 以x为蓝本创建出的副本,与x对象并不相同,这保证了克隆出的对象拥有单独的内存空间;
  2. 源对象和克隆的新对象字节码相同,它们具有相同的类类型,但这并不是强制性的;
  3. 源对象和克隆的新对象利用equals()方法比较时是相同的,但这也不是强制性的。

1.3 Java的浅克隆与深克隆

因为每个类的直接或间接父类都是Object,因此它们都含有clone()方法,但因该方法是protected修饰的,所以我们不能在类外访问该方法。但如果我们要对一个对象进行复制,可以对clone方法进行复写,而Java中提供了两种不同的克隆方式,浅克隆(ShallowClone)和深克隆(DeepClone)。

1.3.1 浅克隆

在浅克隆中,如果源对象的成员变量是值类型,则复制一份给克隆对象;如果源对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说源对象和克隆对象的成员变量指向相同的内存地址。

简单说,在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。我们可以用下图对浅克隆进行展示:

在Java语言中,通过实现Cloneable接口,默认覆盖Object类的clone()方法就可以实现浅克隆。

1.3.2 深克隆

在深克隆中,无论源对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,即深克隆将源对象的所有引用对象也复制一份给克隆对象。

简单来说,在深克隆中,除了对象本身被复制外,对象中包含的所有成员变量也将复制。我们可以用下图对深克隆进行展示:

在Java语言中,如果需要实现深克隆,可以通过实现Cloneable接口,自定义覆盖Object类的clone()方法实现,也可以通过序列化(Serialization)等方式来实现。如果引用类型里面还包含很多引用类型,或者内层引用类型的类里面又包含引用类型,使用clone方法就会很麻烦。这时我们可以用序列化的方式来实现对象的深克隆。

2. hashCode()

hashCode()是Object中的一个native方法,也是所有类都拥有的一个方法,主要返回每个对象的hash值。哈希值是根据地址值换算出来的一个值,并不是实际的地址值,常用于哈希表中,如HashMap、HashTable、HashSet。

关于哈希值,在不同的JDK中算法是不一样的:

  • Java 6、7 中会默认返回一个随机数;
  • Java 8 中默认通过和当前线程有关的一个随机数 + 三个确定值,运用Marsaglia’s xorshift scheme的随机数算法得到的一个随机数。

3. equals(obj)

Object中的equals方法用于判断this和obj本身的值是否相等,即用来判断调用equals方法的对象和形参obj所引用的对象是否是同一对象。所谓同一对象就是指两个对象是否指向了内存中的同一块存储单元,如果this和obj指向的是同一块内存单元,则返回true;如果this和obj指向的不是同一块内存单元,则返回false。如果没有指向同一内存单元,即便是内容完全相等,也会返回false。

我们在使用equals()方法时,需注意下面这些原则:

(1).equals()只能处理引用类型变量;

(2).一般情况下,equals()方法比较的是两个引用类型变量的地址值是否相等;

(3).但是String类、基本类型包装类、File类、Date类等,都重写了Object类的equals()方法,比较是两个对象的"具体内容"是否相同。

另外Java语言规范也要求equals方法具有下面的特性:

  1. 自反性:对于任何非空引用x,x.equals(x)应该返回true;
  2. 对称性:对于任何引用x和y,当且仅当y.equals(x)返回true,x.equals(y)也应该返回true;
  3. 传递性:对于任何引用x,y和z,如果x.equals(y)返回true,y.equals(z)返回true,x.equals(z)也应该返回true;
  4. 一致性:如果x和y引用的对象没有发生变化,反复调用x.equals(y)应该返回同样的结果;
  5. 对于任何非空引用x,x.equals(null)应该返回false。

4. getClass()

getClass()方法用于获取对象运行时的类对象字节码,该方法属于Java的反射机制。该方法的返回值是Class类型,例如 Class c = obj.getClass(); 通过对象c,我们可以获取该对象的所有成员方法,每个成员方法都是一个Method对象;我们也可以获取该对象的所有成员变量,每个成员变量都是一个Field对象;同样的,我们也可以获取该对象的构造函数,构造函数则是一个Constructor对象。

5. toString()

toString()方法可以说是一个进行“自我描述”的方法,当输出某实例对象的信息时,我们可以通过重写该方法来输出自我描述的信息。该方法通常只是为了方便输出本类的描述信息,比如执行System.out.println(xyz)这样的日志语句。

6. wait()、wait(long)、wait(long,int)、notify()、notifyAll()

这几个函数体现的是Java的多线程机制,一般是结合synchronize语句使用。

  • wait()用于让当前线程失去操作权限,当前线程进入等待序列;
  • notify()用于随机通知一个持有对象的锁的线程获取操作权限;
  • wait(long) 和wait(long,int)用于设定下一次获取锁的距离当前释放锁的时间间隔;
  • notifyAll()用于通知所有持有对象的锁的线程获取操作权限。

这几个方法我们后面在分析多线程的面试题时再细说,此处先仅做了解。

7. finalize()

finalize()方法在进行垃圾回收的时候会用到,主要是在垃圾回收时,用于作为确认该对象是否确认被回收的一个标记。我们在使用finalize()方法时要注意:

  • finalize方法不一定会执行,只有在该方法被重写的时候才会执行;
  • finalize方法只会被执行一次;
  • 对象可以在finalize方法中获得自救,避免自己被垃圾回收,同样的自救也只能进行一次;
  • 不推荐Java程序员手动调用该方法,因为finalize方法代价很大。

三. 结论

整体来看,今天的面试题还是很简单的,Object的方法主要就这么几个:

  1. 构造方法;
  2. hashCode()和equals()函数用来判断对象是否相同;
  3. wait()、wait(long)、wait(long,int)、notify()、notifyAll();
  4. toString()和getClass();
  5. clone();
  6. finalize()

我们对每个方法的主要功能简要记住即可,现在你记住了吗?

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/323110.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号