有料面试题之--Object里面的方法
阿里的面试题里面有个题很奇妙:你知道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里面的方法的更多相关文章
- 方法object面试题分析:7JAVA中Object的clone方法详解-克隆-深克隆
时间紧张,先记一笔,后续优化与完善. 每日一道理 翻开早已发黄的页张,试着寻找过去所留下的点点滴滴的足迹.多年前的好友似乎现在看来已变得陌生,匆忙之间,让这维持了多年的友谊变淡,找不出什么亲切 ...
- .NET面试题解析(04)-类型、方法与继承
系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 做技术是清苦的.一个人,一台机器,相对无言,代码纷飞,bug无情.须梦里挑灯,冥思苦想,肝血暗耗,板凳坐穿 ...
- 理解JAVA - 面向对象(object) - 属性,方法
理解JAVA - 面向对象(object) - 属性,方法 多态的体现: 向上造型,父类接收子类对象:向上造型: 从父类角度看不到子类独有的方法:面向对象,人类认知世界的方式:生活中每天都 ...
- 利用Object.prototype.toString方法,实现比typeof更准确的type校验
Object.prototype.toString方法返回对象的类型字符串,因此可以用来判断一个值的类型. 调用方法: Object.prototype.toString.call(value) 不同 ...
- Object类clone方法的自我理解
网上搜帖: clone()是java.lang.Object类的protected方法,实现clone方法: 1)类自身需要实现Cloneable接口 2)需重写clone()方法,最好设置修饰符mo ...
- Cloneable接口和Object的clone()方法
为什么要克隆 为什么要使用克隆,这其实反映的是一个很现实的问题,假如我们有一个对象: public class SimpleObject implements Cloneable { private ...
- JavaScript:Object.prototype.toString方法的原理
在JavaScript中,想要判断某个对象值属于哪种内置类型,最靠谱的做法就是通过Object.prototype.toString方法. var arr = []; console.log(Obje ...
- Object类的方法
一 Object:类Object是类层次结构的跟类,每个类都使用Object作为超类,每个类都是直接或者间接的继承自Object类. Object类的方法: ①public int hashCode( ...
- javascript Object的新方法
今天复习es6,又看到Object的一堆方法,与es5的表现又有不一致,耗费了一整天,整理一下: 前几天在司徒正美的书里又看到了es5 Object的字眼,为了向下兼容,大神们也是牛逼的整理出一系列i ...
- Object 及toString() 方法的重写
Object: 是所有的类的父类 ,Object中所有的方法 , 子类都能使用 , 接口不是Object子类. Person: /*将父类的equals方法 重写 * 不改变父类的源代码 eq ...
随机推荐
- CentOS7下SVN server的安装与配置
CentOS7通过yum install命令进行安装SVN(参考:http://subversion.apache.org/packages.html#centos) $ yum install su ...
- 斐波那契堆(Fibonacci heap)原理详解(附java代码实现)
前言 斐波那契堆(Fibonacci heap)是计算机科学中最小堆有序树的集合.它和二项式堆有类似的性质,但比二项式堆有更好的均摊时间.堆的名字来源于斐波那契数,它常用于分析运行时间. 堆结构介绍 ...
- TortoiseGit用户手册
3 配置TortoiseGit 3.1 生成公钥 生成SSH安全密钥,提供给GIT版本库管理员以访问Git 版本库,点击桌面上生成的图标 然后执行执行“ssh-keygen”生成自己的公钥: 一路回车 ...
- 深入理解JVM之JVM内存区域与内存分配
深入理解JVM之JVM内存区域与内存分配 在学习jvm的内存分配的时候,看到的这篇博客,该博客对jvm的内存分配总结的很好,同时也利用jvm的内存模型解释了java程序中有关参数传递的问题. 博客出处 ...
- try,except用法
lst = ["皇阿玛", "皇额娘", "容嬷嬷", "紫薇"] # 模拟for循环 it = lst.__iter_ ...
- 通过ajax记录打印信息
润乾自带的打印直接可以通过触发js事件来进行调用.onClick="report1_print();return false;" 如果客户需要记录某个用户在某个时间段进行打印 ...
- responsebody和requestbody的使用
Controller的方法上加了一个@ResponseBody,那么他的作用是什么呢?/** * 新增或修改一条对象. */ @RequestMapping("/save_field&quo ...
- https的网站用了百度分享后网站在浏览器中不安全解决方法
本文出至:新太潮流网络博客 一.先下载百度分享需要的所有东西 下载地址:http://pan.baidu.com/s/1boM7N8V 二.打开百度分享,获取到分享的代码 三.将下载好的百度分享需要的 ...
- 使用Axure设计中,大型的后台系统原型总结
使用Axure设计中,大型的后台系统原型总结 2018年4月16日luodonggan 在产品原型设计中,经常会涉及到后台系统原型的设计,如何设计出更规范标准的后台系统原型,是很多产品同行们都会遇到的 ...
- 如何通过rman的增量备份恢复dataguard中standby端的数据
很多正在使用dataguard的客户,都会遇到一个棘手的问题: 在备份端与主库同步的过程中由于网络原因或磁盘问题导致一个或多个归档日志丢失,进而dataguard同步无法继续.很多客户都选择了重新全库 ...