有料面试题之--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 ...
随机推荐
- SSM配置JDBC错误: cquisition Attempt Failed!!!
异常: 警告: com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@20ffa401 -- Acquisition Attempt Fa ...
- 面向连接的传输TCP(一)
这篇博客主要是对计算机网络自顶向上做的阅读笔记,深入地了解TCP 一.TCP连接 1.特点: a.TCP是面向连接的,因为一个进程在向另一个进程进行数据传输之前必须先要握手,即要互相发送报文,以确认信 ...
- js实现unicode码字符串与utf8字节数据互转
js的string变量存储字符串使用的是unicode编码,要保存时必须选择其他编码后进行传输,比如转成utf-8,utf-32等.存储到数据库中为utf-8编码,读取出来如何转换成正确的字符串就成了 ...
- DICOM简介
背景: DICOM分为两大类(这里只是从DICOM相关从业者日常工作角度出发来分类的):1)DICOM医学图像处理,即DCM文件中具体数据的处理,说图像可能有些狭隘,广义上还包括波形(心电).视频(超 ...
- 解决win7无法打开chm格式文件的问题
解决win7无法打开chm格式文件的问题. (一).简单方法(本人用的这个) 1.打开chm2.win7提示安全问题3.chm无法显示内容4.关闭chm5.右键点击chm,点击“解除锁定”,ok 没 ...
- AGC009:Eternal Average
传送门 好神啊 直接考虑一棵 \(n+m\) 个叶子的 \(k\) 叉树,根结点权值为 \(\sum_{i\in m}(\frac{1}{k})^{deep_i}\) 对于一个 \(deep\) 的序 ...
- react知识点汇总
①uncontrolComponent & controlComponent If your form is incredibly simple in terms of UI feedback ...
- OpenGL学习--05--纹理立方体--代码
1.tutorial05.cpp // Include standard headers #include <stdio.h> #include <stdlib.h> // I ...
- sql 单表查询练习
-- 工资高于3000的员工select * from emp where sal > 3000;-- 工资在2500和3000之间的员工select * from emp where sal ...
- 树莓派raspberry Pi2 介绍
Compared to the Raspberry Pi 1 it has: A 900MHz quad-core ARM Cortex-A7 CPU 1GB RAM Like the (Pi 1) ...