阿里的面试题里面有个题很奇妙:你知道Object类里面有哪些方法吗?

绝大部分猿类都知道 有hashcode 、equals 、clone、toString

只有部分人会回答有 wait和notify,notifyall,finalize

我原来也不清楚wait和notify居然是在Object里面定义的~~~~囧

由此会衍生很多问题出来:比如在日常工作中会重写哪些方法?为什么重写equals一定要重写hashcode?深clone和浅clone说下你的认识?wait和notify为什么要定义在Object中,wait和notify是怎么使用的?wait和sleep的区别?finalize的效果和使用场景?

然后我们来一一看下这些问题。

1、一般会重写的的方法:

hashcode、equals、tostring

2、为什么重写equals方法一定要重写hashcode

首先我们看下equals的javadoc里面的说明:

* @return  {@code true} if this object is the same as the obj
* argument; {@code false} otherwise.
含义:只有当equals前后的两个对象是同一个对象的时候,才返回true,否则就是false。

也就是说,我们如果我们不重写hashcode,两个你认为相同的obj,可能出现不同的hashcode,而hashmap和set之类的数据结构都是依赖hashcode来进行的,

如果不重写hashcode就有可能碰到这个情况,当equals为true的时候,hashcode必须完全相同。当hashcode不同的时候,equals必须为false。

如果不覆盖equals,那么默认equals比较的引用的内存地址,如果覆盖了,你就需要自己去保证这些内容的一致。

还有一系列看上去很唬人实际上很好理解的原则在里面:

/*
  * 重写equals必须注意:
  *   1 自反性:对于任意的引用值x,x.equals(x)一定为true
  *   2  对称性:对于任意的引用值x 和 y,当x.equals(y)返回true,y.equals(x)也一定返回true
  *   3 传递性:对于任意的引用值x、y和z,如果x.equals(y)返回true,并且y.equals(z)也返回true,那么x.equals(z)也一定返   回 true
   * 4 一致性:对于任意的引用值x 和 y,如果用于equals比较的对象信息没有被修改,
   *           多次调用x.equals(y)要么一致地返回true,要么一致地返回false
   *   5 非空性:对于任意的非空引用值x,x.equals(null)一定返回false
   **/

3、深clone和浅clone

Object里面有个clone方法是浅clone,clone出来的类,新的对象和原来的对象并不是同一个引用,但是如果类中属性存在引用类型,那么新的类的对应属性也会指向这个引用。

也就是,你如果修改了新对象的引用对象的内容,原来的对象也会发生改变。

如果我们需要clone出来一个完全不同的类,可以通过实现cloneable的protected的clone方法,来确定,

可以通过自己拼接一份新的对象返回,不过对于嵌套层次比较深的类,这是个很浩大的工程。当然也有简单的做法,把对象序列化,然后再反序列化回来其实就是一个新的了。

这种clone之后完全不同的两个对象的情况,就是深clone了。

4、wait和notify为什么要定义在Object中,wait和notify是怎么使用的

wait和notify为什么不在Thread中而是在Object中,其实这个地方稍微有点绕。

我们就假设一种情况吧:A对象,100个线程,线程Thread[1] 持有A对象的锁,其它99个都想使用A,然后就在等待锁。A用完了,怎么通知其他99个?我们是Thread[1]持有其它99个线程的,然后分别去通信通知他们还是通过Object对象直接告诉其他99好呢?

这个很明显吧,我们并不能确定外围有多少个线程,我们只能确定,Object都可以作为锁,然后为什么不用对象本身来管理这些消息通知呢?我们只要在其中一个线程使用完成锁之后,对象把锁丢地上说:兄弟们我的钥匙扔地上了,你们看着办啊。。而不是之前拿钥匙的人,因为这个人没法认识其他所有人,但是凡是关心这个对象的,这个对象肯定都是知道的。

所以这个地方的wait和notify其实Object中定义的~比较口语化,我也不知道怎么更加优雅的表达,那我们就抄一段放这里吧:

5、sleep和wait的区别

sleep是Thread类的静态方法,它生效的也仅仅是当前线程,而不能用 某线程.sleep() .

wait是持有该对象锁的线程主动放弃锁,交出monitor。

sleep本身并不释放所和资源,而只是等待一段时间。wait是交出了锁和资源,后面如果再想获取,需要看自己的实现了。

6、finalize

Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。finalize方法在Object类中是protected方法,也就是你可以自己去重写这个方法,但是除非很特殊的情况,一般没必要自己去重写。

这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。

当垃圾回收器(garbage colector)决定回收某对象时,就会运行该对象的finalize()方法。值得C++程序员注意的是,finalize()方法并不能等同与析构函数。Java中是没有析构函数的。C++的析构函数是在对象消亡时运行的。由于C++没有垃圾回收,对象空间手动回收,所以一旦对象用不到时,程序员就应当把它delete()掉。所以析构函数中经常做一些文件保存之类的收尾工作。但是在Java中很不幸,如果内存总是充足的,那么垃圾回收可能永远不会进行,也就是说filalize()可能永远不被执行,显然指望它做收尾工作是靠不住的。

那么finalize()究竟是做什么的呢?它最主要的用途是回收特殊渠道申请的内存。Java程序有垃圾回收器,所以一般情况下内存问题不用程序员操心。但有一种JNI(Java Native Interface)调用non-Java程序(C或C++),finalize()的工作就是回收这部分的内存。

也就是说,finalize并不保证执行以后就会把内存释放掉,而是会到执行后的下一次垃圾回收才有机会被回收掉。

有料面试题之--Object里面的方法的更多相关文章

  1. 方法object面试题分析:7JAVA中Object的clone方法详解-克隆-深克隆

    时间紧张,先记一笔,后续优化与完善.     每日一道理 翻开早已发黄的页张,试着寻找过去所留下的点点滴滴的足迹.多年前的好友似乎现在看来已变得陌生,匆忙之间,让这维持了多年的友谊变淡,找不出什么亲切 ...

  2. .NET面试题解析(04)-类型、方法与继承

      系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 做技术是清苦的.一个人,一台机器,相对无言,代码纷飞,bug无情.须梦里挑灯,冥思苦想,肝血暗耗,板凳坐穿 ...

  3. 理解JAVA - 面向对象(object) - 属性,方法

    理解JAVA - 面向对象(object) - 属性,方法 多态的体现:    向上造型,父类接收子类对象:向上造型:    从父类角度看不到子类独有的方法:面向对象,人类认知世界的方式:生活中每天都 ...

  4. 利用Object.prototype.toString方法,实现比typeof更准确的type校验

    Object.prototype.toString方法返回对象的类型字符串,因此可以用来判断一个值的类型. 调用方法: Object.prototype.toString.call(value) 不同 ...

  5. Object类clone方法的自我理解

    网上搜帖: clone()是java.lang.Object类的protected方法,实现clone方法: 1)类自身需要实现Cloneable接口 2)需重写clone()方法,最好设置修饰符mo ...

  6. Cloneable接口和Object的clone()方法

    为什么要克隆 为什么要使用克隆,这其实反映的是一个很现实的问题,假如我们有一个对象: public class SimpleObject implements Cloneable { private ...

  7. JavaScript:Object.prototype.toString方法的原理

    在JavaScript中,想要判断某个对象值属于哪种内置类型,最靠谱的做法就是通过Object.prototype.toString方法. var arr = []; console.log(Obje ...

  8. Object类的方法

    一 Object:类Object是类层次结构的跟类,每个类都使用Object作为超类,每个类都是直接或者间接的继承自Object类. Object类的方法: ①public int hashCode( ...

  9. javascript Object的新方法

    今天复习es6,又看到Object的一堆方法,与es5的表现又有不一致,耗费了一整天,整理一下: 前几天在司徒正美的书里又看到了es5 Object的字眼,为了向下兼容,大神们也是牛逼的整理出一系列i ...

  10. Object 及toString() 方法的重写

    Object: 是所有的类的父类  ,Object中所有的方法 , 子类都能使用  ,   接口不是Object子类. Person: /*将父类的equals方法 重写 * 不改变父类的源代码 eq ...

随机推荐

  1. web前端开发教程系列-4 - 前端开发职业规划

    前言 关于我:小天 1). 架构师,项目经理,产品经理 2). 中间件研发 3). VPCC 云计算基础平台管理 4). 智慧旅游 5). 智慧教育 6). 一次失败的创业体验(爱邂逅网) 一. 在开 ...

  2. VS2015编译OpenSSL

    概述 OpenSSL 是一个开源的第三方库,它实现了 SSL(Secure SocketLayer)和 TLS(Transport Layer Security)协议,被广泛企业应用所采用.对于一般的 ...

  3. MyBatis入门(二)—— 输入映射和输出映射、动态sql、关联查询

    一.输入映射和输出映射 1. parameterType(输入类型) 1.1 传递简单类型 <select id="getUserById" parameterType=&q ...

  4. ul制作导航菜单

    首先上图,最终效果: HTML代码: <!DOCTYPE html><html> <head> <meta charset="utf-8" ...

  5. 简单侧边栏js效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. CSS选择器之基本选择器+属性选择器

    1.1      id选择器 #main{ font-size:12px; margin:0; padding:0; } 其中的#main就是id选择器,用于选择HTML页面中id = "m ...

  7. Dynamics 365Online 查询Web Api的请求WebUri

    在on-premises版本中,获取weburi的方式是进设置-自定义项-开发人员资源中查看地址,但online版本中的地址会有些许的差异 online的开发者资源中的地址如下图,如果你在页面java ...

  8. linux yum list、search、-y、install、update、remove、grouplist、groupinstall、groupremove

    redhat使用yum需要付费yum安装的也是rpm包 centos的网络yum源默认已经配置好了,连接的是centos官方yum源,在国外,网速慢 yum源配置在/etc/yum.repos.d下 ...

  9. linux 获取shell内置命令帮助信息 help xx

    shell,命令解释器 shell内置命令有cd/umask/pwd等 help shell内置命令适用于所有用户获取shell内置命令的帮助信息help umaskhelp if

  10. private 与 super

    public class Person { private String name; private int age; } public class Student extends Person { ...